2011-02-14 30 views
8

Cần trợ giúp để ngăn chặn chuỗi Chủ đề nền. Tôi đang cố dừng một chuỗi công nhân nền. Đây là những gì tôi đang làm:Cần trợ giúp để ngăn chặn chủ đề của BackgroundWorker

Mở nút dừng nhấp chuột (UI layer):

if (backgroundWorker.IsBusy == true && 
    backgroundWorker.WorkerSupportsCancellation == true) 
{ 
    backgroundWorker.CancelAsync(); 
} 

Mở sự kiện DoWork (lớp UI):

if ((backgroundWorker.CancellationPending == true)) 
{ 
    e.Cancel = true; 
} 
else 
{ 
    //Function which progresses the progress bar is called 
    //here with its definition in business layer 
} 

Khi sự kiện DoWork là bắn và tôi kiểm soát chương trình là trong các chức năng được xác định trong lớp kinh doanh, làm thế nào để tôi trở lại sự kiện DoWork để thiết lập 'e.Cancel = true'?

Trả lời

2

DoWork sẽ chạy trong chuỗi riêng của nó và không phụ thuộc vào chuỗi GUI.

Bạn làm hầu như mọi thứ đều chính xác. Từ chuỗi GUI, hãy đặt CancellationPending thành true.

Trong phương thức DoWork, bạn có thể có một số loại vòng lặp.

Ở đây bạn kiểm tra xem CancellationPending == true, nhưng ngoài việc đặt e.Cancel thành true, còn bao gồm gọi return để làm cho phương thức trả lại và dừng hiệu quả công nhân. Điều này cũng làm cho sự kiện WorkerCompleted kích hoạt trên luồng GUI nếu phương thức được nối.

Nếu phương pháp DoWork thực hiện một số nhiệm vụ dài mà không được chia thành nhiều phần (ví dụ nếu phương pháp DoWork của bạn trông như thế này:

void DoWork((object sender, DoWorkEventArgs e) 
{ 
    myClass.SomeLongOperation(); 
} 

Sau đó, bạn đang trên may mắn, vì bạn cần phải tự kiểm tra CancellationPending bên trong phương pháp DoWork để có thể dừng nó.Nếu DoWork chính nó "treo" và chờ một thao tác bạn không thể kiểm soát, bạn không thể dừng nó (theo bất kỳ cách nào có trật tự) bằng cách đặt CancellationPending từ GUI chủ đề.

+1

.. Và nếu bạn không stuartd

+1

@Stuart - Điều đó đúng, như đã đề cập trong câu trả lời. Nếu không có vòng lặp, không có cách nào tốt để tắt nó mà không ép buộc chủ đề từ luồng GUI. –

+0

@ Øyvind Knobloch-Bråthen - Xin vui lòng cho tôi biết cách BAD để tiêu diệt chủ đề Backgroundworker một cách mạnh mẽ từ chủ đề GUI là gì. (không có vòng lặp trong DoWork) – Zeeshanef

3

Thiết lập e.Cancel không làm gì cả, nếu hủy bỏ CancendPending là đúng, bạn cần phải thoát khỏi DoWork() bằng cách sử dụng trả về hoặc bất cứ điều gì (sau khi bạn đã dừng những gì bạn đang làm).

Cái gì như:

private void DoWork(...) 
{ 
    // An infinite loop of work! 
    while (true) 
    { 
     // If set to cancel, break the loop 
     if (worker.CancellationPending) 
      break; 

     // Sleep for a bit (do work) 
     Thread.Sleep(100); 
    } 
} 

DoWork() thực hiện trong một thread riêng biệt để thread UI, bạn có thể báo cáo lại cho thread UI sử dụng BackgroundWorkr.ReportProgress().

0

Tiếp tục kiểm tra việc hủy gửi tiền = Cờ thực trong phần khác của logic của bạn và trả lại khi đúng.

2

Khi sự kiện DoWork được kích hoạt và điều khiển chương trình của tôi nằm trong chức năng được xác định trong lớp Doanh nghiệp, làm cách nào để hoàn nguyên về sự kiện DoWork để đặt ‘e.Cancel = true’?

Bạn không. Nếu bạn muốn hủy có thể thực hiện trong khi thực hiện lớp doanh nghiệp của bạn, thì lớp doanh nghiệp của bạn phải hỗ trợ hủy.Vì vậy, bạn có hai tùy chọn:

  1. Trong phương thức DoWork của bạn, chỉ gọi phương thức lớp kinh doanh trong thời gian ngắn và kiểm tra Hủy ở giữa.
  2. Làm cho các phương thức của lớp kinh doanh của bạn bị hủy nhận thức, tức là, chuyển BackgroundWorker cho họ và yêu cầu họ định kỳ kiểm tra Hủy gửi (và trả lại, sau khi đã chuyển thành đúng).
0

Mã chỉ e.Cancel = true chỉ đặt trạng thái trên BackgroundWorker, để biết rằng nó đã bị hủy, nó không thực sự hủy quá trình.

Bạn sẽ phải kiểm tra CancellationPending bên trong vòng lặp của phương thức và break hoặc return.

void DoWork(object sender, DoWorkEventArgs e) { 
    for (int i = 0; i < length; i++) { 
     if(e.CancellationPending) { 
      return; 
     } 
     // Long running code 
    } 
} 
Các vấn đề liên quan