[解決済み] C#のSystem.Threading.Timerが動作していないようです。3秒に一度、高速に動作します。
質問
タイマーオブジェクトがあります。これを1分ごとに実行させたい。具体的には
OnCallBack
メソッドを実行し
OnCallBack
メソッドが実行されている間は非アクティブになります。いったん
OnCallBack
メソッドが終了すると、それは(
OnCallBack
) がタイマーを再起動します。
今、私が持っているのはこんな感じです。
private static Timer timer;
private static void Main()
{
timer = new Timer(_ => OnCallBack(), null, 0, 1000 * 10); //every 10 seconds
Console.ReadLine();
}
private static void OnCallBack()
{
timer.Change(Timeout.Infinite, Timeout.Infinite); //stops the timer
Thread.Sleep(3000); //doing some long operation
timer.Change(0, 1000 * 10); //restarts the timer
}
しかし、どうもうまくいかないようです。3秒に1回の割合で非常に速く実行されます。ピリオド(1000*10)を上げてもです。を見て見ぬふりしているようです。
1000 * 10
何がいけなかったのでしょうか?
どうすればいいのでしょうか?
これはSystem.Threading.Timerの正しい使い方ではありません。Timerをインスタンス化するときは、ほとんどの場合、次のようにする必要があります。
_timer = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
このようにすると、タイマーは指定した時間が経過したときに一度だけ動作するようになります。そして、コールバック関数で、作業が完了したらタイマーを変更します。例
private void Callback( Object state )
{
// Long running operation
_timer.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
}
このように、同時並行性がないため、ロック機構は必要ない。タイマーは次のインターバルが経過した後、次のコールバックを起動します + 長時間実行された操作の時間。
正確にNミリ秒でタイマーを実行する必要がある場合は、ストップウォッチを使って長時間実行されている操作の時間を測定し、適切にChangeメソッドを呼び出すことをお勧めします。
private void Callback( Object state )
{
Stopwatch watch = new Stopwatch();
watch.Start();
// Long running operation
_timer.Change( Math.Max( 0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds ), Timeout.Infinite );
}
I <強い 強く .NET を使っていて CLR を使っている人で Jeffrey Richter の本を読んでいない人には、ぜひとも C# を介した CLR を読んでいない人は、できるだけ早く読むことをお勧めします。タイマとスレッドプールについては、そこで非常に詳細に説明されています。
関連
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み] HttpClientのBaseAddressが機能しないのはなぜですか?
-
[解決済み】.NET 3.5のJITがアプリケーションの実行時に機能しない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない