2011-10-18 19 views
4

Silverlightアプリケーションでは、500msごとに実行する必要があるコードブロックがあります。私はこれを達成するためにDispatcherTimerを使う予定です(下記のコードを参照)。DispatchTimer - 前のティックがまだ実行されている場合にティックイベントが発生するのを防ぐ

DispatcherTimer dt = new DispatcherTimer(); 
dt.Interval = new TimeSpan(0, 0, 0, 0, 500); // 500 Milliseconds 
dt.Tick += new EventHandler(dt_Tick); 
dt.Start(); 

しかし、コードブロックが実行に500ms以上かかることがあります(コードブロックはいくつかのWebサービス呼び出しを行います)。現在コールが進行中であれば、DispatcherTimerは別のイベントをトリガーしないことを確認するにはどうすればよいですか?どのような選択肢があり、何が最良の方法ですか?ロックを使用していますか?

答えて

1

時間がかかりすぎるとティックをスキップすると言います。そうしないと、ロックのために大きなキューが作成されます。 EventHandlerの中のSO

言う:

if(!busy) { 
    busy = true; 

    // some code which could take longer than 500 ms 

    busy = false; 
} 
1

DispatchTimerはこれを行うための任意の巧妙な方法がありますが、私はこのような状況でどうなることはない火にタイマーを取得しようとするではない場合、私は知りません以前の実行が終了していない場合は何もしないようにイベントを取得します。

ロックを使用するには、イベントハンドラの先頭でロックを取得します。ロックが利用できない場合は、ロックを取得して作業を終了して作業を終了したら、その機能を終了します(すでに実行中です)。

希望する方法はMonitor.TryEnterです。ロックを使用する場合と同じようにエラートラップを正しく行う必要があります。

1

前のダニにしてもう一度DispatcherTimerからのコールを取得せずにイベント実行成功しを行うためには、dt_Tickイベントにして入力した後やダニのイベントの最後にstopディスパッチャタイマーを完成する意志初期化startもう一度を呼び出しますDispatcherTimerのIsEnabledが再びtrueになります。

4

DispatcherTimerはディスパッチャスレッド上で実行されるため、同時に2つのハンドラを実行する方法はありません。キューイングされ、別のものの直後に実行される可能性があります。チェックする必要があります。

ただし、は、DispatcherTimerのWebサービスコールを行うべきではありません。それはバックグラウンドスレッドで行います。そうしないと、Webサービスを待っているすべての時間を更新するUIがブロックされます。基本的には、UIスレッドで長時間実行するべきではありません。他のさまざまなタイマー(System.Timers.Timerなど)を使用して、スレッドプールスレッドで定期的に作業を行い、UIに表示する必要のあるデータがある場合はディスパッチャを使用してUIスレッドにコールバックします。

もちろん、新しい種類のタイマーを同時に複数回スレッドするという潜在的な問題が複数のスレッドで発生しています。これを回避する1つの方法は、AutoResetプロパティをfalseに設定し、現在のタイマーの最後に次のタイマーティックをスケジュールすることです。

+0

私はWindows Phone用のSilverlightを使用していることを忘れていました。私はSystem.Timers.Timerを見つけることができません。 – Martin

+0

@Martin:代わりに、System.Threading.Timerを使用してください。同じ基本原則:) –

+0

1つの最後の質問ジョン。 System.Timers.Timerを使用すると、2つのティックイベントが同時に実行される可能性はありますか? – Martin

関連する問題