2012-03-15 1 views
0

У меня есть приложение, которое требует нескольких таймеров обратного отсчета для запуска (некоторые одновременно). Они также обновляют элементы пользовательского интерфейса с оставшимся временем обратного отсчета. Я попытался использовать DispatcherTimer, так как это простой способ взаимодействия с элементами пользовательского интерфейса. Тем не менее, за 300 секунд обратного отсчета он перестает синхронизироваться с реальным временем (из-за интенсивного обновления пользовательского интерфейса) до такой степени, что я получаю 30 секунд на таймере, когда он должен быть 0.Таймер обратного отсчета в случайных точках

Затем я попытался переключиться к System.Threading.Timer (код ниже). Теперь таймер находится на месте и синхронизируется с реальным временем жизни. Тем не менее, таймер прекращает тикать после случайного числа тиков (от 3 секунд до 60 секунд). Я подозреваю, что это либо сборщик мусора, либо Invoke (используемый для обновления пользовательского интерфейса), но на самом деле не имеет знаний продолжать этот путь. Может ли кто-нибудь дать мне представление о том, почему таймер случайно останавливается?

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(); 
} 

ответ

2

Не считайте. Сравните текущее время с временем начала таймера и выполните математику. Таким образом, даже если вы пропустите половину секунды здесь и полсекунды, вы все равно будете спотыкаться вовремя.

Рассмотрим этот код:

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(); 

    } 
+0

работал хорошо, спасибо за помощь! –

0

Это случилось со мной за услугу, которую я писал. Таймер в конечном итоге остановится, и отладка процесса обнаружит, что потоки были собраны в мусор. Мне было предложено установить это свойство .IsBackground = true. Я закончил делать что-то другое, поэтому у меня не было возможности попробовать это. Это может вам помочь.