25

一定間隔で可変長のアクティビティ (データベースのスキャンと更新) を実行する Windows サービスを作成しています。このタスクを頻繁に実行する必要がありますが、処理するコードを同時に複数回実行するのは安全ではありません。

実行が重ならないように、30 秒ごとにタスクを実行するタイマーを最も簡単に設定するにはどうすればよいですか? (System.Threading.Timerこのジョブの正しいタイマーは だと思いますが、間違っている可能性があります)。

4

6 に答える 6

36

タイマーでそれを行うこともできますが、データベースのスキャンと更新を何らかの形でロックする必要があります。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 秒待ち....

于 2009-03-26T01:36:50.227 に答える
29

経過したコードで Monitor.TryEnter を使用します。

if (Monitor.TryEnter(lockobj))
{
  try
  {
    // we got the lock, do your work
  }
  finally
  {
     Monitor.Exit(lockobj);
  }
}
else
{
  // another elapsed has the lock
}
于 2009-03-26T01:43:59.460 に答える
2

ロックする代わりに (これにより、すべての時間指定スキャンが待機し、最終的にスタックする可能性があります)。スレッドでスキャン/更新を開始してから、スレッドがまだ生きているかどうかを確認するだけです。

Thread updateDBThread = new Thread(MyUpdateMethod);

...

private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if(!updateDBThread.IsAlive)
        updateDBThread.Start();
}
于 2009-03-26T03:24:24.600 に答える