2016-11-21 5 views
0

System.Timers.Timer関数をElapsedに設定して使用しています。 'aTimer.Elapsed + = OnTimedEvent`は定期的に定期的に起動するように設定されています。 これは5秒ごとに発生するとします。タイマ(Elapsed関数を複数回呼び出す)

何らかの理由でOnTimedEventの処理が最後により多く、5秒を超えるとどうなりますか。

ドキュメントによれば、イベントは別のThreadPoolスレッドで再度発生する可能性があります。この状況では、イベントハンドラはリエントラントでなければなりません。*

私は理論的には何とかこのことを理解していますが、誰かがこれを私に簡単で実用的な言葉で説明することはできますか?


私のonTimedEventで役立つ場合、私はNetworkStreamから読み込もうとしています。

+0

自分で試してみてください。 'OnTimedEvent'の中に' Thread.Sleep(7000) 'をチャックします。 – Rob

+0

[false]に[AutoResetプロパティ](https://msdn.microsoft.com/en-us/library/system.timers.timer.autoreset(v = vs.110).aspx)を設定してください。アーティクル内のサンプルコードが少し壊れている場合は、Elapsedイベントハンドラの最後にStart()を呼び出して、タイマーに再度ティックを取得させます。そして、イベントハンドラでtry/catch/finallyが大好きです。 –

答えて

1

簡単に言えば、OnTimedEventは、それを同時に通過する複数のスレッドをサポートできる必要があります。どうして?メソッドが実行されている間、タイマーを停止しないと、5秒後に再び起動します。しかし、今回は、最初のスレッドが最初の呼び出しを実行中であるため、別のスレッドで起動します。したがって、2番目のスレッドがメソッドに入ります。この時点で、OnTimedEventがスレッドセーフでない場合、悪いことが起こる可能性があります。

複数のスレッドをサポートする方法について詳しくはGoogleに問い合わせることができます。十分な情報を見つけることができます。

ほとんどの場合、メソッドは実行中にタイマーを停止し、メソッドの最後にタイマーを再起動します。しかし、これはあなたの要件とあなたがやっていることに依存します。ここ

非リエントラント方法の例である:

static int sum = 0; 

int increment(int i) { 
    sum += i; 
    return sum; 
} 

T1はそれを実行する方法の内側にあり、合計に1を加算した場合、それ場合、和が1となるであろうので、それはリエントラントではありませんこの時点で実行制御が実行され、T2に与えられたことを意味する.T2が来ると、sumの値は0ではなく、1になります.T2はsumに1を加えて2を返します。T1が戻ると、それは既に1を返します。つまり、2つのスレッドが異なる結果を残しています:T1は1、T2は2です。したがって、メソッドは再入可能ではありません。

int increment(int sum, int i) 
{ 
    return sum + i; 
} 

今すぐ各スレッドは、彼らがすべての変数ので、メソッドの実行の途中で残していても同じ答えを返します

が上にある:

それは再入を作るために、我々は、単にこれを行いますスレッドごとに共有されません(各スレッドには変数のコピーがあります)。

This SOの回答には、さらに詳しい情報が必要です。

関連する問題