在什么时间间隔内检查 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 循环:

while (true) {
    Console.WriteLine("Hello");
}

while (true) {
    Console.Beep(5000);
}

第一个 while 循环的每次迭代都比第二个循环快,因为Console.Beep(5000)需要 5 秒,而Console.WriteLine只需要几分之一秒。

因此,您不能依靠 while 循环来计算时间。

这是你应该做的:

创建System.Windows.Forms.Timer的实例,而不是System.Timers.TimerSystem.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 秒开始倒计时,并在剩余的几秒钟内写入文本框的每个刻度