毎回バックグラウンドで集中的な作業を実行する1つのスレッドを持つ既存のアプリケーションがありますnumOfMinutesInterval
。これは以前はThread.Sleep
(インターバル期間全体にわたってスリープ)を使用して実行されていましたが、Thread.Sleepは悪であり、デザインがずさんであると読んだので、シグナリングメカニズムに変更したいと思います。以下は私が書いたばかりのコードです(wpfのディスパッチャータイマーを使用していますが、この小さなシナリオでは、winformsタイマーでも同じだと思います)。
ディスパッチャ(UIスレッドで実行)は毎秒ティックし、ティック関数内で間隔が経過したかどうかをチェックし、経過した場合は、manualreseteventを通知しSet()
ます。集中的な作業がインターバル期間を超えて延長された場合、これは悪い設計ではないかと思いますか?を設定したが、作業に1分1秒かかった場合、作業がまだ行われていてワーカースレッドがまだブロックされていないときにティックがイベントを試行しているため、numOfMinutesInterval = 1
1回の呼び出しをスキップすることを意味します。set()
set()
lastWorkDoneTime = DateTime.Now;
呼び出し後に設定したことにも注意してください。Set()
代わりにワーカースレッドに移動する必要がありますか(lastWorkDoneTime = DateTime.Now;
直前に呼び出しmanualResetEvent.WaitOne();
ます)?
これが悪いデザインの場合、それを変更するにはどうすればよいですか?読んでくれてありがとう!
//thread work done here
private void MyDoWork_ThreadStart()
{
while(FlagApplicationStillRunning == true)
{
//do the intensive work here
manualResetEvent.WaitOne();
}
}
// tick every second
private int numOfMinutesInterval = 1;
private DateTime lastWorkDoneTime = DateTime.Now;
private void DispatcherTimer_Tick(object sender, EventArgs e)
{
if((DateTime.Now - lastWorkDoneTime).Minutes > numOfMinutesInterval)
{
manualResetEvent.Set();
lastWorkDoneTime = DateTime.Now;
}
}