我正在为老虎机比赛编写一个小型计圈器,作为一个小型家庭项目。我想实现一个倒数计时器,我已经完成了以下测试:
private Thread countdownThread;
private delegate void UpdateTimer(string update);
UpdateTimer ut;
public LapCounterForm()
{
InitializeComponent();
//...
ut += updateTimer;
countdownThread = new Thread(new ThreadStart(startCountdown));
}
private void startCountdown()
{
Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
System.Diagnostics.Stopwatch stopwatch = new Stopwatch();
long time = 0;
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds <= 5000)
{
time = 5000 - stopwatch.ElapsedMilliseconds;
TimeSpan ts = TimeSpan.FromMilliseconds(time);
ut(ts.Minutes.ToString().PadLeft(2, '0') + ":" + ts.Seconds.ToString().PadLeft(2, '0') + ":" + ts.Milliseconds.ToString().PadLeft(3, '0'));
}
}
private void updateTimer(string text)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<String>(ut), new object[] { text });
}
else
{
lblCountdownClock.Text = text;
}
}
当我开始我的线程时,它可以工作。我得到了我想要的 5 秒倒计时,但我可以看到我在这个过程中使用了很多 CPU(我的 8 线程 i7 2600k 的 12%)。
我想我可以通过每 10 毫秒而不是每毫秒更新一次 UI 来大大减少这种负载,但我不知道如何做到这一点,除了if(time % 10 == 0)
在制作TimeSpan
和更新 UI 之前使用,但我怀疑这将是一样的由于 while 循环,效率低下。
我在重新发明轮子吗?我希望我的计时器尽可能准确(至少对于老虎机单圈时间记录,也许 UI 不需要如此频繁地更新)。
编辑:我尝试按照评论中的建议注释掉实际的字符串操作和 UI 更新。现在,当我启动我的线程时,我的整个 UI 都会挂起,直到线程退出,我仍然得到 12% 的 CPU 使用率。我怀疑 while 循环会占用大量 CPU 时间。
更新:我使用了 Kohanz 发布的多媒体计时器(此处)以及 Daniel 的回答。我根本不再使用另一个线程,我只是制作了其中一个计时器对象并有一个滴答事件处理程序来计算单击开始按钮和滴答事件之间的时间。我什至可以将我的滴答时间设置为 1 毫秒,这样我就可以看到很酷的倒计时了,而且它显然使用了 0% 的 CPU :) 我对此很满意。