2

特定の作業を行う System.Timers.Timer で実行されている Windows サービスが既にあります。しかし、いくつかの作業を同時に実行したいのですが、異なるスレッドで実行したいと考えています。

別の System.Timers.Timer インスタンスを作成するように言われました。これは正しいです?この方法は並行して動作しますか?

例えば:

System.Timers.Timer tmr1 = new System.Timers.Timer();
tmr1.Elapsed += new ElapsedEventHandler(DoWork1);
tmr1.Interval = 5000;

System.Timers.Timer tmr2 = new System.Timers.Timer();
tmr2.Elapsed += new ElapsedEventHandler(DoWork2);
tmr2.Interval = 5000;

tmr1tmr2を異なるスレッドで実行して、 と を同時に、つまり同時に実行できるようにしますDoWork1か?DoWork2

ありがとう!

4

4 に答える 4

6

間違いではありません。

気をつけて。System.Timers.Timer は、Elapsed イベントごとに新しいスレッドを開始します。Elapsed イベント ハンドラーに時間がかかりすぎると、問題が発生します。前の呼び出しがまだ完了していなくても、ハンドラーは別のスレッドで再度呼び出されます。これにより、診断が難しいバグが発生する傾向があります。AutoReset プロパティを false に設定することで回避できること。また、イベント ハンドラーで必ず try/catch を使用してください。例外は診断なしで飲み込まれます。

于 2013-08-01T18:37:35.203 に答える
2

すこし。まず、次の MSDN ページをチェックしてくださいSystem.Timers.Timer: http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

あなたが懸念する必要があるセクションは以下に引用されています:

SynchronizingObject プロパティが null の場合、ThreadPool スレッドで Elapsed イベントが発生します。Elapsed イベントの処理が Interval より長く続く場合、イベントは別の ThreadPool スレッドで再び発生する可能性があります。この場合、イベント ハンドラーは再入可能にする必要があります。

基本的に、これはTimerのアクションが実行される場所で、それぞれTimerが独自のスレッドを持つのではなく、デフォルトでシステムを使用しThreadPoolてアクションを実行することを意味します。

物事を同時に実行したい (すべて同時に開始する) が同時に実行したい場合は、複数のイベントを経過イベントに置くことはできません。たとえば、VS2012でこれを試しました:

    static void testMethod(string[] args)
    {
        System.Timers.Timer mytimer = new System.Timers.Timer();
        mytimer.AutoReset = false;
        mytimer.Interval = 3000;

        mytimer.Elapsed += (x, y) => {
            Console.WriteLine("First lambda.  Sleeping 3 seconds");
            System.Threading.Thread.Sleep(3000);
            Console.WriteLine("After sleep");
        };
        mytimer.Elapsed += (x, y) => { Console.WriteLine("second lambda"); };
        mytimer.Start();
        Console.WriteLine("Press any key to go to end of method");
        Console.ReadKey();
    }

出力は次のとおりです。

メソッドの最後に移動するには、任意のキーを押します

最初のラムダ。

睡眠 3 秒

睡眠後

2 番目のラムダ

したがって、それらは同時にではなく連続して実行されます。Elapsedしたがって、タイマーの実行ごとに「一連のことが起こる」ようにする場合は、ハンドラーで一連のタスクを起動する (またはアクションを含む ThreadPool をキューに入れる) 必要があります。それらをマルチスレッド化する場合とそうでない場合がありますが、私の単純な例ではそうではありませんでした。

私のコードを自分で試してみてください。何が起こっているのかを説明するのは非常に簡単です。

于 2013-08-01T18:46:44.870 に答える