在什么时间间隔内检查 while 子句中的条件
本文关键字:子句 条件 while 检查 时间 在什么 | 更新日期: 2023-09-27 17:55:42
如何在显示剩余等待时间的同时等待指定时间?
我现在像这样解决了它,但我觉得这是一个非常糟糕的方法:
//This is running in a BackgroundWorker:
Stopwatch watch = new Stopwatch();
watch.Start();
while(watch.ElapsedMilliseconds != SecondsToWait * 1000)
{
TimeToNextRefresh = ((SecondsToWait * 1000) - watch.ElapsedMilliseconds) / 1000;
Thread.Sleep(1);
}
watch.Stop();
所以在这里我猜测条件(watch.ElapsedMilliseconds != SecondsToWait * 1000
)每毫秒检查一次。
所以主要问题是;检查时的状态在什么时期和/或我如何改进我编写的代码?
这取决于 while 循环中的代码是什么!
例如,如果您在 while 循环中编写一些非常长/耗时的代码,则 while 循环或课程的每次迭代都将比只有短/快速代码的 while 循环长。
比较这两个 while 循环:
while (true) {
Console.WriteLine("Hello");
}
和
while (true) {
Console.Beep(5000);
}
第一个 while 循环的每次迭代都比第二个循环快,因为Console.Beep(5000)
需要 5 秒,而Console.WriteLine
只需要几分之一秒。
因此,您不能依靠 while 循环来计算时间。
这是你应该做的:
创建System.Windows.Forms.Timer
的实例,而不是System.Timers.Timer
或System.Threading.Timer
。我发现第一个最有用(其他更高级)。
Timer timer = new Timer();
timer.Interval = 1000; // 1000 means 1000ms aka 1 second
timer.Tick += TimerTicked;
timer.Start();
现在编译器会告诉你TimerTicked
没有定义,所以让我们去定义它:
private void TimerTicked(object sender, EventArgs e) {
}
现在一切就绪。TimerTicked
中的代码将每隔一秒调用一次。
假设您要测量 10 秒的时间。10 秒后,您想做某事。因此,首先在类级别创建一个名为 secondsLeft
的变量:
int secondsLeft = 10;
现在在 TimerTicked
中,您要检查secondsLeft
是否为 0。如果是,那就做某事,否则,减去一个:
if (secondsLeft == 0) {
DoSomething();
} else {
secondsLeft--;
}
剩下的时间secondsLeft
了!您可以将其显示在标签或其他东西上。
要暂停计时器,只需
timer.Stop();
检查while
状况的确切时间间隔很难预测。 Thread.Sleep(1);
仅告知操作系统您希望线程休眠至少 1 毫秒。无法保证您的线程将在正好 1 毫秒后再次处于活动状态。实际上,您可以确定它将不止于此。线程在 1 毫秒后再次调度,但在他获得 CPU 时隙之前会有延迟。
您想要的循环间隔实际上取决于您希望如何显示剩余时间。如果只想显示秒,为什么每毫秒更新一次显示,尽管文本每 1000 毫秒才会更改一次?
像这样的循环可能不是实现类似内容的好方法。我会推荐一个System.Threading.Timer
:
// this Timer will call TimerTick every 1000ms
Timer timer = new Timer(TimerTick, null, 0, 1000);
并实现处理程序
public void TimerTick(object sender)
{
// update your display
}
请注意,您将再次在 UI 线程上看到"更新显示"部分,因为此方法由不同线程上的Timer
调用。
如果计算时间超过 1 毫秒,这段代码确实可以进行无限循环。
你可以通过一个简单的System.Winforms.Forms.Forms.Timer来实现你想要的行为,如下所示:
private int tickCount = 0;
private int remaining = 10;
private void timer1_Tick(object sender, EventArgs e)
{
remaining--;
textBox1.Text = remaining.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 1000;
timer1.Enabled = true;
}
有了这个,您可以从 10 秒开始倒计时,并在剩余的几秒钟内写入文本框的每个刻度