2

以下のクラスは、.Net Windows サービスからのものです。メソッドDoSomeDatabaseStuffは、最初の開始時に 10 分かかりますが、時間が経過すると、このメソッドは再度呼び出されません。

public class Test
{
        public void Start()
        {
            DoSomeDatabaseStuff();

            _oTimer = new Timer(60000);
            _oTimer.Elapsed += OnTimeout;
            _oTimer.AutoReset = true;
            _oTimer.Start();
        }

        private void OnTimeout(object source, ElapsedEventArgs e)
        {
            DoSomeDatabaseStuff();

            _oTimer = new Timer(60000);
            _oTimer.Elapsed += OnTimeout;
            _oTimer.AutoReset = true;
            _oTimer.Start();
        }
}
4

4 に答える 4

6

このコードには多くの深刻な問題があります:

  • Start メソッドがサービスの OnStart() メソッドであることが意図されている場合、サービスを開始することはできません。OnStart() は 30 秒以内に完了する必要があります。タイマーを初期化するだけで、他には何もしません
  • Elapsed イベント ハンドラーで別のタイマーを作成するのは重大な間違いです。イベント ハンドラーが 2 回実行されるようになりました。2 回目に呼び出された後、3 回実行されます。など。
  • テスト プログラムは、コードがサービスで実行される方法をテストしません。イベント ハンドラーが実行される前にテストが完了するため、Elapsed イベント ハンドラーは決して実行されません。あなたの観察を説明するもの
  • Elapsed イベント ハンドラーで try/catch を使用する必要があります。そうしないと、診断なしで例外が飲み込まれます。System.Timers.Timer クラスはそのように厄介です。代わりに System.Threading.Timer を優先してください また、あなたの観察についても説明します
  • イベント ハンドラーが再入可能であることを確認する必要があります。イベント ハンドラーの前回の呼び出しがまだビジー状態のときに再度実行できます。これは、タスクに 1 分以上かかる場合に発生します。これが良い結末になることはめったにありません。AutoReset = false を設定することは、この再入を回避する簡単な方法です。イベント ハンドラーの最後でタイマーを開始して、それを繰り返すようにします。
于 2013-09-13T12:44:48.267 に答える