メソッドを持つクラスが非常にX分実行され、別のメソッドがイベントハンドラを呼び出しました。どちらも静的リストのステータスを変更します。以下は静的変数をロックする - タイマーとイベントハンドラ
それはそれはいくつかのロジックを行いますと、プロセスが存在しない場合、それはと同じプロセスを更新します(存在する場合)イベントハンドラメソッドは、プロセスのためにそれをチェックするコード
public class DatabaseOps
{
private static Timer timer = null;
private static IDictionary<int, Model.Process> allProcessDetails = new Dictionary<int, Model.Process>();
public DatabaseOps()
{
if (timer.IsNull())
{
timer = new Timer(5000);
timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
}
}
// Timer event
private async void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
foreach (var processDetails in tempAllProcessDetails)
{
// Some logic
allProcessDetails.Remove(processDetails.Key);
await Task.Run(() => SendProcess(processDetails.Value));
}
}
// Method invoked from event handler
public void UpdateProcess(Model.Process processDetails)
{
if (!allProcessDetails.ContainsKey(processDetails.ProcessID))
{
// Add process to allProcessDetails
// Some logic
}
else
{
// Modify existing process in allProcessDetails
// Some logic
}
}
}
です新しい論理。
タイマはX間隔ごとに実行され、すべてのプロセスの現在のステータスを外部システムに送信し、プロセスをallProcessDetails
から削除します。私はUpdateProcess
にチェックコードallProcessDetails.ContainsKey(processDetails.ProcessID)
を確保する必要がある。ここ
は、ロックを追加私の理解あたりとしてOnTimerElapsed
に削除コードallProcessDetails.Remove(processDetails.Key)
と競合しない同じコードを使用して作成され、別のスレッドからのアクセスをブロックしますここでは、別のコードシーケンス(タイマーとイベントハンドラ)から作成された別のスレッドによって辞書にアクセスします。
したがって、イベントハンドラメソッドが現在タイマーメソッドでアクセス可能な同じキーにアクセスするのを防ぐにはどうすればよいですか除去のために。
あなたが本当に別の 'OnTimerElapsed'かかわらず、前の' OnTimerElapsed'は、実行が完了したのを発射する必要がありますか?また、 'System.Timers.Timer'(' System.Threading.Timer'と同様に)は、スレッドプールスレッド上でコールバックが実行されるマルチスレッドタイマーです。だから、上記を知って、なぜあなたは 'Task.Run'が必要ですか? –
@AlexeyGroshev私は次のタイマーイベントの前にタスクが完了するのを待っていません。また、Task.Runより前のタイマーイベントで実装されたロジックは、タイマーインターバルよりも時間がかかりません。 –