2009-05-29 12 views
2

私はメインスレッドといくつかの計算を行う別のスレッドでWindowsフォームを持っています。フォームのステータスバーを、他のスレッドで行われている作業から更新したいと思います。これを行う最善の方法は何ですか?別のスレッドから進捗バーを更新する

これまでのところ私が試したことはすべて、物事が本当にゆっくりと動くようにしています。 Visual Studio 2005を使用しています。

+0

あなたはもっと具体的にする必要があります - 何が遅いですか?どのようにスレッドを使用しますか? –

答えて

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が...それがあるべき姿に更新されます決定づけるために取得

  • ワーカースレッドは、Invokeのように処理を進める前にUIスレッドからの応答を待つ必要はありません。
  • Invokeが課すUIとワーカースレッドの間の緊密な結合が壊れます。
  • かなり効率的です。
  • UIおよびワーカースレッドのスループットが向上します。
  • BeginInvokeの場合のようにUIメッセージキューを飽和させる可能性はありません。
  • ワーカースレッドからUIを更新する必要があるたびに、Invokeのコードをコードに埋め込む必要はありません。
関連する問題