0

複数のカウントダウン タイマーを実行する必要があるアプリケーションがあります (いくつかは同時に)。また、カウントダウンの残り時間で UI 要素を更新します。UI要素とやり取りする簡単な方法であるため、DispatcherTimerを使用してみました。ただし、300 秒のカウントダウンを超えると、(UI の更新が多いため) リアルタイムと同期しなくなり、タイマーが 0 になるはずのときにタイマーの残り時間が 30 秒になるまでになります。

次に、System.Threading.Timer (以下のコード) に切り替えてみました。現在、タイマーはスポットオンで、実際の時間と同期しています。ただし、Timer は、ランダムな数のティック (3 秒から 60 秒の間) の後、ティックを停止します。ガベージ コレクターが起動しているか、Invoke (UI の更新に使用) のいずれかであると思われますが、このパスを続行するための知識は実際にはありません。タイマーがランダムに停止する理由について、誰かが私に洞察を与えることができますか?

private int counter = 500;    
private void btnTopBlue_Click(object sender, RoutedEventArgs e)
{
    btnTopBlue.Content = counter.ToString();
    Timer dt = new Timer(topBlue_Tick, null, 1000, 1000);
}
private void topBlue_Tick(object sender)
{
     if (counter > 0)
     {
         counter--;
         Dispatcher.BeginInvoke(() => btnTopBlue.Content = counter.ToString());    
     }
     else
         ((Timer)sender).Dispose();
 }
4

2 に答える 2

2

数えないでください。現在の時刻をタイマーの開始時刻と比較し、計算を行います。そうすれば、ここで 0.5 秒、あちらで 0.5 秒を逃したとしても、まだ間に合います。

次のコードを検討してください。

    private static DateTime EndTime { get; set; }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        DispatcherTimer dt = new DispatcherTimer();
        dt.Interval = TimeSpan.FromSeconds(.1);


        dt.Tick += (s, evt) =>
                       {
                           var remaining = EndTime - DateTime.Now;

                           timeRemaining.Text = string.Format("{0:0.0}", remaining.TotalSeconds);

                           if(remaining.TotalSeconds <= 0)
                           {
                               dt.Stop();
                           }
                       };

        EndTime = DateTime.Now + TimeSpan.FromSeconds(30);
        dt.Start();

    }
于 2012-03-15T17:30:40.350 に答える
0

これは私が書いていたサービスのために私に起こりました。タイマーは最終的に停止し、プロセスをデバッグすると、スレッドがガベージコレクションされていることがわかりました。.IsBackground=trueプロパティを設定するとこれが修正されることが私に提案されました。何か違うことをしてしまったので、試してみる機会がありませんでした。それはあなたを助けるかもしれません。

于 2012-03-15T17:17:15.993 に答える