2011-10-25 15 views
5

Tôi đang viết một ứng dụng Windows Forms trong C# thực hiện nhiều quy trình chạy dài trên một lần nhấp nút. Điều này làm cho GUI đóng băng cho đến khi thực thi. Ngoài ra, trong quá trình thực thi, tôi đang ghi thông tin trạng thái & vào một Hộp danh sách. Tuy nhiên, cho đến khi thực hiện xong, trạng thái không được cập nhật trong hộp danh sách. Làm thế nào tôi nên mã để tình trạng là nhận được cập nhật trong hộp danh sách song song với việc thực hiện và do đó GUI không đóng băng.Thực thi không đồng bộ trong các hình thức cửa sổ

Tôi mới sử dụng luồng. Bạn có thể vui lòng cho một số ví dụ về cách thực hiện điều này không?

Cảm ơn trước sự giúp đỡ của bạn.

Trả lời

12

Cách đơn giản nhất nhưng hiệu quả để xử lý các tình huống này là sử dụng BackgroundWorker.

Bạn đặt mã nặng của mình trong trình xử lý sự kiện DoWork và cập nhật GUI của bạn thông qua trình xử lý sự kiện ProgressChanged.

Bạn có thể tìm thấy một hướng dẫn here
Hoặc thậm chí tốt hơn họ thực hiện một "cách" tại msdn
Nếu bạn có thắc mắc cụ thể hơn sau khi đọc nó, tôi sẽ được hạnh phúc để bắt buộc.

+0

Cảm ơn rất nhiều. Giải pháp rất hữu ích – RSP

4

Như con khỉ đầu chó cho biết một con đường để đi là cách tiếp cận nhân viên Bối cảnh một cách khác nếu bạn đang sử dụng Net 4 hoặc cao hơn có thể được sử dụng Task lớp

nhiệm lớp đơn giản hoá việc thực hiện các mã trên nền và giao diện người dùng chủ đề khi cần thiết . Sử dụng lớp công tác, bạn có thể tránh phải viết thêm mã thiết sự kiện và callbacks bằng cách sử dụng công tác Continuation

Reed Copsey, Jr. có series rất tốt trên Parallelism trên Net cũng có một cái nhìn vào nó

ví dụ một cách làm việc đồng bộ có thể là

//bad way to send emails to all people in list, that will freeze your UI 
foreach (String to in toList) 
{ 
    bool hasSent = SendMail(from, "password", to, SubjectTextBox.Text, BodyTextBox.Text); 
    if (hasSent) 
    { 
     OutPutTextBox.appendText("Sent to: " + to); 
    } 
    else 
    { 
     OutPutTextBox.appendText("Failed to: " + to); 
    } 
} 

//good way using Task class which won't freeze your UI 
string subject = SubjectTextBox.Text; 
string body = BodyTextBox.Text; 
var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
List<Task> mails = new List<Task>(); 
foreach (string to in toList) 
{ 
    string target = to; 
    var t = Task.Factory.StartNew(() => SendMail(from, "password", target, subject, body)) 
    .ContinueWith(task => 
    { 
     if (task.Result) 
     { 
      OutPutTextBox.appendText("Sent to: " + to); 
     } 
     else 
     { 
      OutPutTextBox.appendText("Failed to: " + to); 
     } 
    }, ui); 
} 
+0

Hãy cẩn thận vì thư viện song song không phải lúc nào cũng tạo một chuỗi mới. Ví dụ, Parallel.Foreach sẽ không tạo ra một luồng cho mỗi vòng lặp khác nhau. –

Các vấn đề liên quan