5

Silverlight アプリには、500 ミリ秒ごとに実行する必要があるコード ブロックがあります。これを実現するために DispatcherTimer を使用する予定です (以下のコードを参照)。

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

ただし、コード ブロックの実行に 500 ミリ秒以上かかる場合があります (コード ブロックは Web サービスの呼び出しを行います)。通話が現在進行中の場合、DispatcherTimer が別のイベントをトリガーしないようにするにはどうすればよいですか? どのようなオプションがあり、最良の方法は何ですか? ロックを使用していますか?

4

4 に答える 4

5

はディスパッチャー スレッドでDispatcherTimer のみ実行されるため、2 つのハンドラーを同時に実行することはできません。もちろん、それらがキューに入れられ、次々に実行される可能性があります-確認する必要があります.

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

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

于 2011-10-18T13:22:56.573 に答える
1

時間がかかりすぎる場合はティックをスキップします。そうしないと、ロックのために巨大なキューが発生します。

したがって、イベントハンドラで次のように言います。

if(!busy) {
  busy = true;

  // some code which could take longer than 500 ms

  busy = false;
}
于 2011-10-18T13:20:24.137 に答える
1

DispatchTimer にこれを行うための巧妙な方法があるかどうかはわかりませんが、この状況で行うことは、タイマーがイベントを発生させないようにするのではなく、前のイベントが終了していない場合にイベントが何もしないようにすることです。走る。

イベント ハンドラーの先頭でロックを取得することにより、ロックを使用してこれを行うことができます。ロックが利用できない場合は、ロックを取得して作業を行い、作業が完了したらロックを解放する場合は、関数を終了します (既に実行されています)。

必要なメソッドはMonitor.TryEnterであり、ロックを使用する場合と同様に、エラー トラップが正しく行われていることを確認する必要があります。

于 2011-10-18T13:21:03.793 に答える
1

DispatcherTimer からの呼び出しを再度取得せずにイベントを正常に実行するには、前のティックstopで、イベントに入った後にディスパッチャー タイマーを完了しdt_Tick、ティック イベントの最後にDispatcherTimerのIsEnabledstartを再び true に初期化します。 .

于 2011-10-18T13:22:22.670 に答える