2009-05-29 43 views
2

我在主線程和另一個線程做了一些計算。我想從另一個線程中正在完成的工作中更新表單上的狀態欄。什麼是最好的方法來做到這一點?從另一個線程更新進度欄

到目前爲止,我所試過的一切都讓事情真的很慢。我使用Visual Studio 2005

+0

你必須要更加具體 - 什麼是慢?你如何使用線程? – 2009-05-29 02:25:07

回答

2

確保您只能從主線程更新用戶界面,否則你就會有問題。您可以通過調用Invoke來切換線程上下文。這裏有一個很好的帖子here

1

你可以發送消息到主線程,並得到它的更新進度條,雖然你那麼需要檢查的消息。您也可以執行與輪詢功能相同的操作。

1

您可以使用編組技術(如Control.Invoke)在可以安全操作UI元素的UI線程上執行委託,但該方法不太好。實際上,如果你想要做的只是更新簡單的進度信息,這是一種可怕的方法。

到目前爲止,這樣做的最好的方法是:

  • 讓你的工作線程發佈進度信息共享變量。
  • 讓您的UI線程通過System.Windows.Forms.Timers在適合您的時間間隔內進行輪詢。

下面是它可能是什麼樣子。

public class Example : Form 
{ 
    private volatile int percentComplete = 0; 

    private void StartThreadButton_Click(object sender, EventArgs args) 
    { 
    StatusBarUpdateTimer.Enabled = true; 
    new Thread(
    () => 
     { 
     for (int i = 1; i <= 100; i++) 
     { 
      DoSomeWork(); 
      percentComplete = i; 
     } 
     }).Start(); 
    } 

    private void StatusBarUpdateTimer_Tick(object sender, EventArgs args) 
    { 
    yourStatusBarPanel.Text = percentComplete.ToString() + "%"; 
    StatusBarUpdateTimer.Enabled = percentComplete < 100; 
    } 
} 

這種運作良好,這是因爲:

  • UI線程獲取UI得到的時間和頻率更新中...的方式,它應該是決定!
  • 工作線程無需等待來自UI線程的響應,然後就可以像Invoke那樣繼續進行響應。
  • 它打破了Invoke強加的用戶界面和工作線程之間的緊密耦合。
  • 它更有效率......相當。
  • 您可以在UI和工作線程上獲得更高的吞吐量。
  • BeginInvoke一樣,沒有使UI消息隊列飽和的機會。
  • 每次您需要從工作線程更新UI時,您不必亂拋垃圾代碼與Invoke調用。