2008-10-15 29 views
6

Tôi đã thực hiện một số nghiên cứu và tôi thực sự không thể tìm thấy một cách ưa thích để cập nhật các điều khiển biểu mẫu từ một chuỗi công nhân trong C#. Tôi biết về thành phần BackgroundWorker, nhưng cách tốt nhất để làm điều đó mà không cần sử dụng thành phần BackgroundWorker là gì?Cách tốt nhất để cập nhật điều khiển biểu mẫu từ chuỗi công việc là gì?

Trả lời

10

Có một quy tắc chung chung là không cập nhật giao diện người dùng từ bất kỳ chuỗi nào khác ngoài chính chuỗi giao diện người dùng. Sử dụng các tính năng của BackgroundWorker là một ý tưởng hay, nhưng bạn không muốn và một cái gì đó đang xảy ra trên một luồng khác, bạn nên thực hiện một "Invoke" hoặc BeginInvoke để buộc ủy nhiệm thực hiện phương thức trên thread UI.

Edit: Jon B làm điểm tốt này trong các ý kiến:

Hãy ghi nhớ rằng Gọi() là đồng bộ và BeginInvoke() là không đồng bộ. Nếu bạn sử dụng Invoke(), bạn phải cẩn thận để không gây ra tình trạng bế tắc . Tôi sẽ giới thiệu BeginInvoke() trừ khi bạn thực sự cần cuộc gọi để được đồng bộ.

Một số đơn giản mã ví dụ:

// Updates the textbox text. 
private void UpdateText(string text) 
{ 
    // Set the textbox text. 
    m_TextBox.Text = text; 
} 

public delegate void UpdateTextCallback(string text); 

// Then from your thread you can call this... 
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
    new object[]{"Text generated on non-UI thread."}); 

Đoạn mã trên là từ một hỏi thường gặp về nó here và còn tham gia nhiều hơn một here.

+0

Chính xác thì m_TextBox.Invoke làm gì? Liệu nó buộc các đại biểu được thực hiện trên thread UI? – Yttrium

+4

Chính xác. Hãy nhớ rằng Invoke() là đồng bộ và BeginInvoke() là không đồng bộ. Nếu bạn sử dụng Invoke(), bạn phải cẩn thận không gây ra bế tắc. Tôi muốn giới thiệu BeginInvoke() trừ khi bạn thực sự cần cuộc gọi để được đồng bộ. –

+0

Cuộc gọi tốt, Jon B. Tôi nên đề cập đến điều đó. Tôi sẽ chỉnh sửa để phản ánh quan điểm. –

5

Tại sao bạn không muốn làm điều đó bằng cách sử dụng BackgroundWorker? Nó có một sự kiện gọi lại tuyệt vời được gọi là ProgressChanged cho phép chuỗi giao diện người dùng biết về các bản cập nhật, hoàn hảo cho các bản cập nhật kiểu thanh progess và tương tự.

link to details

1

Có một cuộc thảo luận liên quan đến here này và một here.

Về cơ bản, bạn sử dụng Gọi để thực hiện nó.

Best of luck!

1

Tôi cũng sẽ xem xét InvokeRequired (chỉ dành cho VS2008) khi gọi Invoke. Có những lúc bạn sẽ không cập nhật giao diện người dùng từ một chuỗi riêng biệt. Nó tiết kiệm chi phí của việc tạo đại biểu, v.v.

if (InvokeRequired) 
     { 
      //This.Invoke added to circumvent cross threading exceptions. 
      this.Invoke(new UpdateProgressBarHandler(UpdateProgressBar), new object[] { progressPercentage }); 
     } 
     else 
     { 
      UpdateProgressBar(progressPercentage); 
     } 
Các vấn đề liên quan