0

GUI と連携している多くの短いタスクを実行する必要がある場合、BackgroundWorkerタスクごとに別のソリューションを使用する必要がありますか、それとも他のソリューションを使用する必要がありますか?

編集

つまり、datagridview (200 行 x 50 列) のすべてのセルを 5 秒ごとに更新するということです。すべてのセルはイメージを格納します。

4

2 に答える 2

2

私が多くの小さなタスクを扱っているとき、私はThreadPoolそれらを扱う良い方法であることに気付く傾向があります。次のように、バックグラウンドスレッドにデリゲートをディスパッチできます。

ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc));

オブジェクトをその状態としてスレッドに渡すこともできます。オブジェクトをパラメーターとして受け取るデリゲートを検討してください。あなたはこれを呼ぶことができます:

ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc), state);

ここで、stateは、スレッドが処理する方法を知っているオブジェクトです。

編集ThreadPoolアプローチはシナリオにうまく機能するはずです。GUIを変更するコードは、GUIスレッドで呼び出す必要があることを確認してください。そうしないと、いくつかのクロススレッド例外が発生します。

于 2012-08-10T11:17:07.257 に答える
2

BackgroundWorker長時間実行されるタスクに適している場合は、ThreadPoolのようなものが必要です。これは非常に大雑把な例です:

QueueUserWorkItemワーカーメソッドを指定し、そのメソッドが機能するオブジェクトを渡すことができます。

ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), object);

次にDoWork、すべての魔法が発生するメソッドがあります。

public void DoWork(object sender)
{
     object s = (object)sender;

     this.Invoke(new ThreadDone(ReportProgress), result);
}

this.Invoke(new TaskDone(ReportProgress));これは、メインスレッドで実行されているコードを安全に呼び出して、から処理されたデータでUIを更新することに注意してくださいDoWork。これは、プライベートデリゲートを介して行われます。

private delegate void ThreadDone(object yourObject);

これは次のように呼ばれます。

private void ReportProgress(object yourObject)
{
       //update UI
}

Interlockedこれを使用して、カウンターオブジェクトを追跡することにより、タスクがいつ完了したかを確認することもできます。

foreach (string s in strings)
{
      ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), s);
      Interlocked.Increment(ref workItems);
}

次に、単一のスレッドが完了したときにデクリメントし、いつかworkItemsを簡単にチェックしますworkItems == 0

Interlocked.Decrement(ref workItems);

if (workItems == 0)
{
       this.Invoke(new TaskDone(WorkComplete));
}

お役に立てれば。

于 2012-08-10T11:31:55.523 に答える