2011-11-01 107 views
10

我想用C#进行倒计时,并显示格式的时间:C#倒计时

hour:minutes:seconds 

我已经试过这样:

var minutes = 3; //countdown time 
    var start = DateTime.Now; 
    var end = DateTime.Now.AddMinutes(minutes); 
    Thread.Sleep(1800); 
    if (??) // I tried DateTime.Now > end not works 
    { 
     //... show time 
     label1.Text = "..."; 
    } 
    else 
    { 
    //done 
     label1.Text = "Done!"; 
    } 

不同方式也是解决这个问题出现了。在此先感谢

+0

如果要定期更新的标签,你需要像一个循环。 – svick

+2

@javasocute我做了他,我会怀疑他的理智。这是Winforms,.net有处理这些东西的完美机制。没有必要为这样的小东西带来JavaScript。 – CodesInChaos

回答

28

您不应该在这里使用Thread.Sleep。 UI线程上的Thread.Sleep线程会阻塞UI,并且在另一个线程上使用它会由于线程同步而导致额外的复杂性。

如果您有C#5或异步CTP,您可能会编写与您所做的代码非常相似的代码,因为您会获得基于延续的等效Thread.Sleep,该代码不会阻止UI。

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

对于其他格式化选项见Standard TimeSpan Format Strings

该代码仍然存在的一个问题是,如果系统时钟更改,它将无法正常工作。

当使用DateTime.Now而不是DateTime.UtcNow时,从夏令时切换到夏时制或更改时区时也会中断。既然你想识别某个时间点(而不是显示时间),你应该使用UTC而不是本地时间。

+0

非常感谢! +1为好的答案,但我有一个问题在statament:'错误:运算符'<'不能应用于'System.TimeSpan'和'int''类型的操作数如何修复它? –

+0

@TheMask使用'TimeSpan.Zero'而不是'0' – CodesInChaos

+1

CodeInChaos:事情真正起作用的人。完美的作品。非常感谢。 :) –

0

您的代码设置变量,然后进入睡眠3分钟,以便if语句不会执行,直到它离开睡眠状态。无论是设立一个新的线程来更新UI或做这样的事......

while (DateTime.now < end) { 
    label1.Text = "..."; 
    Thread.Sleep(#); //Pick a second, or 5 or whatever 
} 

label1.Text = "Done!"; 

有了第二个线程你仍然可以做的东西在你的程序,而它的工作原理。 “搞定!”将在其完成后出现。

+1

使用计时器,而不是'Thread.Sleep()'。使用睡眠是一种线程的浪费。 –

+0

非常感谢,我不是一个C#人的心脏,只是建立他的代码。 – Grambot

+0

他们在Java中有定时器:) –

5

我会使用一个像这样的计时器。首先是几个实例变量。

private int _countDown = 30; // Seconds 
private Timer _timer; 

,并在构造函数或Load事件

_timer = new Timer(); 
_timer.Tick += new EventHandler(timer_Tick); 
_timer.Interval = 1000; 
_timer.Start(); 

,最后事件处理

void timer_Tick(object sender, EventArgs e) 
{ 
    _countDown--; 
    if (_countDown < 1) 
    { 
     _countDown = 30; 
    } 
    lblCountDown.Text = _countDown.ToString(); 
} 
1

你也可以使用一个定时器,因为这将处理所有的问题像UI锁定。 您可以使用定时器System.Windows.Forms.Timer。在MSDN库中,您可以找到使用它的示例。

WinForms-Timer还处理跨越Timer线程和UI线程的调用。

- SeriTools