2012-07-16 61 views
6

Tôi có một ứng dụng đơn giản kích hoạt một loạt các tác vụ dữ liệu chuyên sâu. Tôi không có kinh nghiệm với WinForms và tôi đã tự hỏi cách tốt nhất để làm điều này mà không cần khóa giao diện. BackgroundWorker có thể được sử dụng lại hay có cách nào khác để làm điều này không?WinForm Đa luồng. Sử dụng backgroundWorker hay không?

Cảm ơn

+0

Tôi sẽ sử dụng nền tảng. – Tomtom

+0

Nếu bạn chỉ cần một chủ đề khác, tôi sẽ sử dụng một nhân viên nền, chúng rất dễ sử dụng và hầu hết công việc khó khăn đã được thực hiện, cung cấp cho bạn các sự kiện thẳng về phía trước cho các giai đoạn hoàn thành công việc khác nhau. – ThePower

+0

Bạn có ý nghĩa gì khi sử dụng lại? –

Trả lời

6

backgroundWorkerthể được sử dụng.

lợi ích của nó - nó cho phép bạn cập nhật thanh tiến trình và tương tác với các điều khiển giao diện người dùng. (WorkerReportsProgress)

Cũng có cơ chế hủy. (WorkerSupportsCancellation)

enter image description here

3

BackgroundWorker là một chủ đề cũng bao gồm đồng bộ hóa thông báo. Ví dụ: nếu bạn muốn cập nhật giao diện người dùng của mình khi quá trình quét hoàn tất, thông thường Thread không thể truy cập các đối tượng giao diện người dùng (chỉ có chuỗi giao diện người dùng mới có thể thực hiện điều đó); do đó, BackgroundWorker cung cấp trình xử lý sự kiện đã hoàn thành chạy trên luồng giao diện người dùng khi thao tác hoàn tất.

để biết thêm xem: Walkthrough: Multithreading with the BackgroundWorker Component(MSDN)

và một mẫu mã đơn giản:

var worker = new System.ComponentModel.BackgroundWorker(); 
worker.DoWork += (sender,e) => Thread.Sleep(60000); 
worker.RunWorkerCompleted += (sender,e) => MessageBox.Show("Hello there!"); 
worker.RunWorkerAsync(); 
2

Bạn có thể sử dụng BackgroundWorker cho các yêu cầu như vậy. Dưới đây là một mẫu mà updates a label status based on percentage task [long running] completion. Ngoài ra, có một lớp nghiệp vụ mẫu đặt một số giá trị và giá trị được đặt trở lại giao diện người dùng thông qua trình xử lý ProgressChanged. DoWork là nơi bạn viết logic nhiệm vụ chạy dài của mình. Sao chép-Dán mã dưới đây sau khi thêm một nhãn và thành phần nền tảng trên một ứng dụng Winforms & cho nó một shot. Bạn có thể gỡ lỗi trên các trình xử lý khác nhau [RunWorkerCompleted, ProgressChanged, DoWork] và xem phương thức InitWorker. Hãy chú ý đến số cancellation feature.

using System.ComponentModel; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form3 : Form 
    { 
     private BackgroundWorker _worker; 
     BusinessClass _biz = new BusinessClass(); 
     public Form3() 
     { 
      InitializeComponent(); 
      InitWorker(); 
     } 

     private void InitWorker() 
     { 
      if (_worker != null) 
      { 
       _worker.Dispose(); 
      } 

      _worker = new BackgroundWorker 
      { 
       WorkerReportsProgress = true, 
       WorkerSupportsCancellation = true 
      }; 
      _worker.DoWork += DoWork; 
      _worker.RunWorkerCompleted += RunWorkerCompleted; 
      _worker.ProgressChanged += ProgressChanged; 
      _worker.RunWorkerAsync(); 
     } 


     void DoWork(object sender, DoWorkEventArgs e) 
     { 
      int highestPercentageReached = 0; 
      if (_worker.CancellationPending) 
      { 
       e.Cancel = true; 
      } 
      else 
      { 
       double i = 0.0d; 
       int junk = 0; 
       for (i = 0; i <= 199990000; i++) 
       { 
        int result = _biz.MyFunction(junk); 
        junk++; 

        // Report progress as a percentage of the total task. 
        var percentComplete = (int)(i/199990000 * 100); 
        if (percentComplete > highestPercentageReached) 
        { 
         highestPercentageReached = percentComplete; 
         // note I can pass the business class result also and display the same in the LABEL 
         _worker.ReportProgress(percentComplete, result); 
         _worker.CancelAsync(); 
        } 
       } 

      } 
     } 

     void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Cancelled) 
      { 
       // Display some message to the user that task has been 
       // cancelled 
      } 
      else if (e.Error != null) 
      { 
       // Do something with the error 
      } 
     } 

     void ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      label1.Text = string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage); 
     } 
    } 

    public class BusinessClass 
    { 
     public int MyFunction(int input) 
     { 
      return input+10; 
     } 
    } 
} 
+0

Cảm ơn bạn đã phản hồi chi tiết. Mối quan tâm của tôi là thêm "logic nhiệm vụ chạy dài" của tôi vào sự kiện DoWork.Tôi có một số nhiệm vụ cần chạy và có vẻ như không thực tế để thêm tất cả chúng vào sự kiện DoWork. – Brian