再入可能性の問題があり、UIを保持しないようにする別の方法が常にあるため、Application.DoEventsには近づきません。私は長い間、マルチスレッドの単純な代替手段として、Application.Idleイベントでバックグラウンド作業を行うことを好みました。ただし、長時間実行されるタスクの場合、DoEventsループを使用してApplication.Idleで操作を実行することは許容されますか?
class LongRunningTask : IDisposable {
public LongRunningTask(IEnumerable<Tidbit> listOfDataToBeProcessed) {
Application.Idle += OnIdle;
foreach(Tidbit t in listofDataToBeProcessed) {
tidbits.Enqueue(t);
}
}
// Small pieces of data to process
Queue<Tidbit> tidbits = new Queue<Tidbit>();
void OnIdle(object sender, EventArgs e) {
while(tidbits.Count > 0) {
var tidbit = tasks.Dequeue();
tidbit.Process();
// Process any messages that have queued up
// while the data was being processed
Application.DoEvents();
}
}
public void Dispose() {
Application.Idle -= OnIdle;
}
}
ここでのロジックは、DoEventsを呼び出すApplication.Idleイベントでは、キューに入れられたメッセージがないため、コードを再入力できないようにする必要があるということです。各tidbitは、メッセージキュー(またはUI)を大幅に保持しないように十分に高速に処理されます。
それで、このアプローチに害や欠点はありますか?つまり、アイドルイベントでDoEventsを呼び出すのは安全ですか?C#5にこの種の状況に対処する機能があることは知っていますが、 C#5を使用していない人(現時点ではほとんどの人)にとって、そして一般的な好奇心から、これは良いことです予定?または、マルチスレッドに頼らずに、長時間実行される操作中にメッセージを処理するためのより簡単な代替手段はありますか?
これが魔法の弾丸だとは思わないでください。非同期アプローチと同じ落とし穴があることを私は知っています。私は、彼のアプリケーションを一貫した状態に保つことができなければならないことを認識しています。そして、私はマルチスレッドソリューションがあることを知っています。私はそれらを避けています。なんで?マルチスレッドはもっと複雑だからです。それは非現実的だとは思いません。