110

.NETには3つのタイマータイプがあることを認識しています( .NET Frameworkクラスライブラリのタイマークラスの比較を参照)。メインスレッドがビジーの場合、他のタイプがドリフトする可能性があるため、スレッドタイマーを選択しました。これは信頼できるものである必要があります。

タイマーの制御でこのタイマーが機能する方法は別のスレッドに配置されるため、ビジーでないときに親スレッドで完了した作業の開始に合わせて常にチェックすることができます。

コンソールアプリケーションでのこのタイマーの問題は、タイマーが別のスレッドで動作している間、メインスレッドがアプリケーションを閉じるために何もしていないことです。

ループを追加しようとしましたwhile trueが、タイマーが切れるとメインスレッドがビジー状態になります。

4

3 に答える 3

62

のようなものを使用Console.ReadLine()してメインスレッドをブロックできるため、他のバックグラウンドスレッド(タイマースレッドなど)は引き続き機能します。AutoResetEventを使用して実行をブロックし、(必要に応じて)そのAutoResetEventオブジェクトでSet()メソッドを呼び出して、メインスレッドを解放することもできます。また、Timerオブジェクトへの参照がスコープ外に出てガベージコレクションされないようにしてください。

于 2008-08-01T12:56:37.920 に答える
22

ManualResetEventを使用して、処理の最後にメインスレッドをブロックしReset()、タイマーの処理が終了したらそれを呼び出すことを検討してください。これを継続的に実行する必要がある場合は、コンソールアプリではなくサービスプロセスに移動することを検討してください。

于 2008-08-01T12:55:42.413 に答える
1

MSDNおよびその他の回答によると、System.Threading.Timerをすぐに終了せずに使用するコンソールアプリケーションの最小限の動作例:

private static void Main()
{
    using AutoResetEvent autoResetEvent = new AutoResetEvent(false);
    using Timer timer = new Timer(state => Console.WriteLine("One second has passed"), autoResetEvent, TimeSpan.Zero, new TimeSpan(0, 0, 1));
    autoResetEvent.WaitOne();
}
于 2020-12-10T16:48:40.317 に答える