一定間隔で可変長のアクティビティ (データベースのスキャンと更新) を実行する Windows サービスを作成しています。このタスクを頻繁に実行する必要がありますが、処理するコードを同時に複数回実行するのは安全ではありません。
実行が重ならないように、30 秒ごとにタスクを実行するタイマーを最も簡単に設定するにはどうすればよいですか? (System.Threading.Timer
このジョブの正しいタイマーは だと思いますが、間違っている可能性があります)。
一定間隔で可変長のアクティビティ (データベースのスキャンと更新) を実行する Windows サービスを作成しています。このタスクを頻繁に実行する必要がありますが、処理するコードを同時に複数回実行するのは安全ではありません。
実行が重ならないように、30 秒ごとにタスクを実行するタイマーを最も簡単に設定するにはどうすればよいですか? (System.Threading.Timer
このジョブの正しいタイマーは だと思いますが、間違っている可能性があります)。
タイマーでそれを行うこともできますが、データベースのスキャンと更新を何らかの形でロックする必要があります。lock
複数の実行が発生するのを防ぐには、単純に同期するだけで十分な場合があります。
そうは言っても、操作が完了してからタイマーを開始し、1回だけ使用してから停止する方が良いかもしれません。次の操作の後に再起動してください。これにより、イベント間に 30 秒 (または N 秒) が与えられ、オーバーラップの可能性がなく、ロックも発生しません。
例 :
System.Threading.Timer timer = null;
timer = new System.Threading.Timer((g) =>
{
Console.WriteLine(1); //do whatever
timer.Change(5000, Timeout.Infinite);
}, null, 0, Timeout.Infinite);
すぐに作業 .....完了...5 秒待ち....すぐに作業 .....完了...5 秒待ち....
経過したコードで Monitor.TryEnter を使用します。
if (Monitor.TryEnter(lockobj))
{
try
{
// we got the lock, do your work
}
finally
{
Monitor.Exit(lockobj);
}
}
else
{
// another elapsed has the lock
}
ロックする代わりに (これにより、すべての時間指定スキャンが待機し、最終的にスタックする可能性があります)。スレッドでスキャン/更新を開始してから、スレッドがまだ生きているかどうかを確認するだけです。
Thread updateDBThread = new Thread(MyUpdateMethod);
...
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(!updateDBThread.IsAlive)
updateDBThread.Start();
}