GUI と連携している多くの短いタスクを実行する必要がある場合、BackgroundWorker
タスクごとに別のソリューションを使用する必要がありますか、それとも他のソリューションを使用する必要がありますか?
編集
つまり、datagridview (200 行 x 50 列) のすべてのセルを 5 秒ごとに更新するということです。すべてのセルはイメージを格納します。
GUI と連携している多くの短いタスクを実行する必要がある場合、BackgroundWorker
タスクごとに別のソリューションを使用する必要がありますか、それとも他のソリューションを使用する必要がありますか?
編集
つまり、datagridview (200 行 x 50 列) のすべてのセルを 5 秒ごとに更新するということです。すべてのセルはイメージを格納します。
私が多くの小さなタスクを扱っているとき、私はThreadPool
それらを扱う良い方法であることに気付く傾向があります。次のように、バックグラウンドスレッドにデリゲートをディスパッチできます。
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc));
オブジェクトをその状態としてスレッドに渡すこともできます。オブジェクトをパラメーターとして受け取るデリゲートを検討してください。あなたはこれを呼ぶことができます:
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc), state);
ここで、stateは、スレッドが処理する方法を知っているオブジェクトです。
編集:ThreadPool
アプローチはシナリオにうまく機能するはずです。GUIを変更するコードは、GUIスレッドで呼び出す必要があることを確認してください。そうしないと、いくつかのクロススレッド例外が発生します。
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));
}
お役に立てれば。