Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# while子句中的条件在什么时间间隔内检查?_C#_Wpf_Timer_While Loop - Fatal编程技术网

C# while子句中的条件在什么时间间隔内检查?

C# while子句中的条件在什么时间间隔内检查?,c#,wpf,timer,while-loop,C#,Wpf,Timer,While Loop,如何在显示剩余等待时间的同时等待指定的时间 我现在是这样解决的,但我觉得这是一个非常糟糕的方法: //This is running in a BackgroundWorker: Stopwatch watch = new Stopwatch(); watch.Start(); while(watch.ElapsedMilliseconds != SecondsToWait * 1000) { TimeToNextRefresh = ((SecondsToWait * 1000) -

如何在显示剩余等待时间的同时等待指定的时间

我现在是这样解决的,但我觉得这是一个非常糟糕的方法:

//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.elapsedmillesons!=SecondsToWait*1000
)每毫秒检查一次


所以主要的问题是,;while检查时的状态是在什么时期,以及/或者如何改进我编写的代码?

很难预测while检查时的确切时间间隔<代码>线程睡眠(1)只告诉操作系统您希望线程睡眠至少1毫秒。不能保证你的线程会在1毫秒后再次激活。事实上,你可以肯定的是,它将不止于此。线程将在1毫秒后再次调度,但会有一个延迟,直到他获得CPU时间槽

循环所需的间隔实际上取决于显示剩余时间的方式。如果只想显示秒,为什么要每毫秒更新一次显示,尽管文本只会每1000毫秒更改一次

这样的循环可能不是实现这样的东西的好方法。我建议使用
系统.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线程上再次出现“更新您的显示”部分,因为此方法是由另一个线程上的
计时器调用的。

如果计算只需超过1毫秒,则此代码实际上可以进行无限循环

您可以使用简单的System.Winforms.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秒开始倒数,而你在文本框中写的每一个勾号,剩下的秒数取决于while循环中的代码

例如,如果在while循环中编写一些非常长/耗时的代码,则while循环或过程的每次迭代都将比只有短/快代码的while循环长

比较这两个while循环:

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

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

所以你不能依靠while循环来计算时间

这就是你应该做的:

创建
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
的实例。我发现第一个最有用(其他的更高级)

现在,编译器将告诉您未定义
TimerTicked
,因此让我们定义:

private void TimerTicked(object sender, EventArgs e) {

}
现在你都准备好了。
timer选中的
中的代码将每隔一秒钟调用一次

假设你想测量10秒的时间。10秒钟后,你想做点什么。因此,首先在类级别创建名为
secondsLeft
的变量:

int secondsLeft = 10;
现在,在
timerChecked
中,您要检查
secondsLeft
是否为0。如果是的话,做点别的,减去一:

if (secondsLeft == 0) {
    DoSomething();
} else {
    secondsLeft--;
}
还有
secondsLeft
是剩余的时间!你可以把它显示在标签上

要暂停计时器,只需

timer.Stop();

使用计时器对象。编写这样的热循环从来都不是一个好主意<代码>线程。睡眠
不能解决任何问题。@CodyGray您能提供一个例子吗?我只是想暂停执行。。。。如何使用计时器执行此操作?为什么要“暂停”执行?为什么会有用?这不是真正的停顿。我正在刷新一个数据网格,并希望显示下一次刷新的剩余时间(CurrentTimeSpan为1分钟)。如何执行此操作取决于您正在编写的应用程序类型。这是一个控制台应用程序吗?Windows窗体?WPF?如果您告诉我们您试图解决的更大的问题是什么,这可能会有所帮助,因为您编写的代码没有任何用处。我正在使用WPF,我想刷新DataGrid(因此每分钟我都从sql获取一些数据)。当我得到数据后,我在CompletedEvent中重新启动了Worker,并希望显示下一次刷新之前的剩余时间。感谢您的努力。我很抱歉问了这么多问题,但有没有一种方法可以让剩下的时间进入下一个节拍?@裸体你为什么想要这样?现在每隔1000毫秒调用一次此
计时器_Tick
(因此每秒调用一次)。由于我不知道您的项目/代码,所以计算下次更新之前的时间的逻辑取决于您。虽然此方法也可能不是每1000毫秒调用一次(但会在几纳秒之后调用),但它的精确性足以显示秒数。
计时器。计时器
/
线程。计时器
?听起来你不推荐它。您可以只编写
var timer=new System.Windows.Forms.timer()以清楚地显示您选择的选项,而不引入所述歧义。顺便说一句,wpf中的winforms是。作为初学者,当我第一次看到这三个计时器时,我发现winforms是最直观的。线程计时器真的。。。肮脏的我尝试了
Timer.Timer
,但它(似乎)没有在UI线程上运行事件处理程序。这就是我不喜欢它的原因。当我写这个答案时,我不知道OP是在处理WPF。即使我知道,我仍然会发布答案,因为OP似乎是个初学者。我认为winforms定时器最适合初学者,因为它直观。我的意思是,OP可以在他有更多经验的时候尝试其他人@SinatrYes,在WinForms应用程序中,应该使用WinForms计时器。其他计时器都是为不同的目的而设计的。它不是直观的,因为它设计得更好,它是直观的,因为它设计用于WinForms应用程序。如果您有一个控制台应用程序,使用WinForms计时器将不会是直观的
if (secondsLeft == 0) {
    DoSomething();
} else {
    secondsLeft--;
}
timer.Stop();