2012-02-27 14 views
2

System.Timers.Timerを使用する場合、前のイベントが終了していない場合は、ElapsedEventを実行できますか? 私は、実行が完了する前に、予想以上に時間がかかり、タイマーの間隔が稼働しているとします。その後何が起こるのですか?同じSystem.Timers.Timerの2つのElapsedEventを同時に実行できる

MSDNで読むことができたのはSystem.Timersで、スレッドタイマーはシングルスレッドで実行されます。 私は、同時に2つ(またはそれ以上!)のイベントを誤って実行することに懸念しています。

答えて

4

はい、Elapsedイベントが再度発生します。

If the SynchronizingObject property is Nothing, the Elapsed event is raised on a ThreadPool thread. If the processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. In this situation, the event handler should be reentrant.

はまた、停止イベントが間隔イベントを尊重し、別のスレッドにキューイングされる可能性があるためElapsedイベントの終わりを保証するものではありませんStopメソッドを使用して: 慎重に言うMSDNのドキュメントを読みます。再び MSDNを読ん

この状況

2

はい彼らができるの処理方法を明確にしています。

2つの解決策:

  • 一度に実行されているから、複数のスレッドを防ぐために、あなたのタイマーでSynchonizingObjectを指定します。ここでの問題は、実装がタイマーのタイムアウトよりも時間がかかる場合、コールがバックアップされることです。

  • デリゲートの開始時にタイマーを停止し、最後にもう一度やり直してください。これはより一般的なパターンのようですが、コールバック内でタイミングを取らない限り、イベントが正確に発生しないことを意味します。これは問題である場合とそうでない場合があります。

2

はい、絶対に。これを実証する短いプログラムです:

using System; 
using System.Threading; 
using Timer = System.Timers.Timer; 

class Test 
{ 
    static void Main() 
    { 
     Timer timer = new Timer(1000); 
     timer.Elapsed += ElapsedHandler; 
     timer.Enabled = true; 
     Thread.Sleep(10000); 
     timer.Enabled = false; 
    } 

    static void ElapsedHandler(object sender, EventArgs e) 
    { 
     int id = Thread.CurrentThread.ManagedThreadId; 
     Console.WriteLine("{0}: Starting to sleep", id); 
     Thread.Sleep(5000); 
     Console.WriteLine("{0}: Exiting", id); 
    } 
} 

どのように対処するかはあなた次第です。あなたは可能性:

  • より多くの制御を得るためにSynchronizingObjectプロパティを使用するかどうかにかかわらずに言って、原子またはカウンタのいくつかの並べ替えをしてください本当にプロセス「ダニ」
  • は失敗に終わった「のいくつかの並べ替えを取ります"アクション

...本当に状況によって異なります。

関連する問題