標準System.Timers.Timerの動作に問題があります。タイマーは、一定間隔でElapsedイベントを発生させます。しかし、Elapsedイベントハンドラ内の実行時間がタイマーインターバルを超えると、スレッドプールはイベント処理をキューに入れ始めます。これは私の場合の問題です。これは、私のElapsedイベントハンドラでは、データベースから何らかのデータを取得して何かを実行し、最後に結果をデータベースに戻すためです。しかし、データの取り扱いは一度だけ行う必要があります。したがって、System.Timers.Timerの経過イベントをキューに入れないようにする方法があります。出力は、としてここになりますSystem.Timers.Timerがスレッドプール上で実行するためのキューイングを防止する方法
public class EntryPoint
{
private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
}
static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
System.Timers.Timer MyTimer = new System.Timers.Timer(1000);
MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Start();
Console.ReadLine();
MyTimer.Stop();
}
}
そして可能:
Current time 03.02.2011 0:00:09 on the thread 4
Current time 03.02.2011 0:00:10 on the thread 5
Current time 03.02.2011 0:00:12 on the thread 6
Current time 03.02.2011 0:00:13 on the thread 7
Current time 03.02.2011 0:00:14 on the thread 8
Current time 03.02.2011 0:00:15 on the thread 9
Current time 03.02.2011 0:00:16 on the thread 10
Current time 03.02.2011 0:00:17 on the thread 11
Current time 03.02.2011 0:00:18 on the thread 12
Current time 03.02.2011 0:00:19 on the thread 13
Current time 03.02.2011 0:00:30 on the thread 4
Current time 03.02.2011 0:00:30 on the thread 5
考えられる解決策:この問題の実例として、あなたは、次のテストプログラムを検討することができ
1)それは、次の要因によって影響を受けました:C# Timer vs Thread in Service
そして、ここでのサンプル上記に係るようなコードがあります
public class EntryPoint
{
private static System.Timers.Timer MyTimer;
private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
MyTimer.Enabled = true;
}
static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
MyTimer = new System.Timers.Timer(1000);
MyTimer.AutoReset = false;
MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Enabled = true;
Console.ReadLine();
}
}
2)第2の方法がするSynchronizingObjectについてですが、それだけでWindowsフォームアプリケーションまたはその希望のオブジェクトを実装するためのコードの必要な追加開発のための価値がありますISynchronizeInvokeインターフェイスを実装する必要があります。あなたが見つけることができるこの方法の詳細here
したがって、私は最初の解決策を優先します。
タイマーは問題ありません...これはすべての場所で発生しました。実際には、Elapsedイベントをキューに入れていることがうれしいです。これがハードウェアの割り込みだった場合は、あなたのインターバルを吹き飛ばし、あなたはそれを取り戻すことができません。 –
データを1回だけ処理する必要がある場合は、繰り返すタイマーはなぜですか、またはX時間ごとに最大1回ということですか? – Chris
@Chris私のケースでは、別のアプリケーションがデータベースにデータを保存し、アプリケーションがそのデータを読み込んで処理する必要があります。 – apros