次のコードTimerRecalcStatisticsElapsed
では、実行中のインスタンスを 1 つだけ持つ必要があります。このコールバックが呼び出すワーカー メソッドは、一度に最大 1 つのスレッドが実行されるように、順番に実行されます。
質問パート 1:
タイマーのコールバックがスレッドプール スレッドを実行する場合 (別のスレッドでコールバックを実行するのではなく)、スレッドプールがキューに入れられ、条件に基づいて後で実行するためにスレッドを延期する可能性があると言うのは正しいですか (MaxThreads に達した、スレッドプールの内部ロジック) ?
質問パート 2:
1 つのタイマー コールバックが即時実行以外のキューに入れられる可能性があると仮定すると、それは任意の数のスレッド コールバックが同時に実行される可能性があることを意味しますか?
質問パート3
パート 2 が正しいと仮定すると、以下のコードで複数のコールバックが同時に動作する可能性があるということですか?
私が質問している理由は、マルチ CPU サーバーで実行されているこのクラスのインスタンスが数千あるためです。の順不同の操作と一致するデータ破損も見られます// Do Work Here
。
さておき
// Do work here
System.Collections.Dictionary と内部的に連携し、y の値を編集します。また、シリアルに呼び出される後続の関数のいくつかのキーも削除されます。その関数には、最初の呼び出しで以前に存在していたキー (x) がありません。これは、最終ステートメントで競合状態があるためだと思いますobj.cleanupdata()
public class SystemTimerTest
{
readonly System.Timers.Timer timerRecalcStatistics;
readonly System.Diagnostics.Stopwatch stopwatchForRecalcStatistics = new System.Diagnostics.Stopwatch();
public SystemTimerTest(TimeSpan range, DataOverwriteAction action)
{
int recalculateStatisticsEveryXMillseconds = 1000;
timerRecalcStatistics = new System.Timers.Timer(recalculateStatisticsEveryXMillseconds);
timerRecalcStatistics.AutoReset = true;
timerRecalcStatistics.Elapsed += new System.Timers.ElapsedEventHandler(TimerRecalcStatisticsElapsed);
timerRecalcStatistics.Interval = recalculateStatisticsEveryXMillseconds;
timerRecalcStatistics.Enabled = true;
this.maxRange = range;
this.hashRunningTotalDB = new HashRunningTotalDB(action);
this.hashesByDate = new HashesByDate(action);
this.dataOverwriteAction = action;
}
private void TimerRecalcStatisticsElapsed(object source, System.Timers.ElapsedEventArgs e)
{
stopwatchForRecalcStatistics.Start();
Console.WriteLine("The TimerRecalcStatisticsElapsed event was raised at {0}", e.SignalTime.ToString("o"));
// DO WORK HERE
stopwatchForRecalcStatistics.Stop();
double timeBuffer = GetInterval(IntervalTypeEnum.NearestSecond, e.SignalTime) - stopwatchForRecalcStatistics.ElapsedMilliseconds;
if (timeBuffer > 0)
timerRecalcStatistics.Interval = timeBuffer;
else
timerRecalcStatistics.Interval = 1;
stopwatchForRecalcStatistics.Reset();
timerRecalcStatistics.Enabled = true;
}
}