Вы не должны использовать Thread.Sleep
здесь. Thread.Sleep
в потоке пользовательского интерфейса блокирует пользовательский интерфейс, а использование его в другом потоке приводит к дополнительной сложности из-за синхронизации потока.
Если у вас есть C # 5 или асинхронный CTP, вы, вероятно, можете написать код, очень похожий на тот, что вы делали, поскольку тогда вы получите эквивалент на основе продолжения Thread.Sleep
, который не блокирует пользовательский интерфейс.
В стандартном C # 4 я бы использовал System.Windows.Forms.Timer
.
Чтобы начать обратный отсчет:
var minutes = 3; //countdown time
var start = DateTime.UtcNow; // Use UtcNow instead of Now
endTime = start.AddMinutes(minutes); //endTime is a member, not a local variable
timer1.Enabled = true;
В обработчике таймера вы пишете:
TimeSpan remainingTime=endTime-DateTime.UtcNow;
if(remainingTime<TimeSpan.Zero)
{
label1.Text = "Done!";
timer1.Enabled=false;
}
else
{
label1.Text = remainingTime.ToString();
}
Другие параметры форматирования см. Стандартные строки формата TimeSpan .
Одна проблема, которая остается с этим кодом, состоит в том, что он не будет работать правильно, если системные часы изменятся.
При использовании DateTime.Now
вместо DateTime.UtcNow
оно также прерывается при переключении с / на летнее время или при смене часового пояса. Поскольку вы хотите определить определенный момент времени (а не время отображения), вы должны использовать UTC вместо местного времени.