C# 我被困在我的while循环中,以计时器的运行时间为条件
我正在启动一个计时器,希望该方法等待一段时间。我搜索了其他类似的问题,但找不到明确的答案。 为什么下面的代码会冻结应用程序? 运行时间从0开始,间隔为1000(1秒)C# 我被困在我的while循环中,以计时器的运行时间为条件,c#,while-loop,timer,C#,While Loop,Timer,我正在启动一个计时器,希望该方法等待一段时间。我搜索了其他类似的问题,但找不到明确的答案。 为什么下面的代码会冻结应用程序? 运行时间从0开始,间隔为1000(1秒) private void timer2\u勾选(对象发送方,事件参数e) { elapsedtime2++; } //这是我的方法 timer2.Start(); 而(延迟时间2
private void timer2\u勾选(对象发送方,事件参数e)
{
elapsedtime2++;
}
//这是我的方法
timer2.Start();
而(延迟时间2<3)
{
}
timer2.Stop();
您可以使用事件来获得所需的行为:
private int elapsedtime2 = 0;
private ManualResetEventSlim mre = new ManualResetEventSlim();
private void timer2_Tick(object sender, EventArgs e)
{
elapsedtime2++;
if(elapsedtime2 >= 3)
{
mre.Set();
}
}
如果已用时间变量具有预期值,则可以设置事件
mre.Reset();
timer2.Start();
mre.Wait();
timer2.Stop();
在启动计时器之前,先取消设置事件。启动计时器后,等待事件设置。暂停执行一秒钟的最简单方法是:
Thread.Sleep(1000);
如果您熟悉async/await,则async等效项为:
await Task.Delay(1000);
对
elapsedTime2
的访问没有任何锁定,但它是由多个线程读取/写入的。运行时完全有权在elapsedtime2<2
检查中删除对elapsedtime2
的读取,这意味着您的循环变成了无限循环(+1)。感谢您的评论。我正在努力学习,这是我一直在寻找的建设性的批评。现在我知道出了什么问题。我将研究访问锁定以及何时/如何/为什么可以在运行时删除读取。@canton7您能提供一个参考或什么吗?我不知道运行时可以做这样的事情:删除读取
@rytisk我手头没有,但是许多语言的一个共同特点是允许编译器/运行时(甚至CPU)对读取/写入进行重新排序,这样重新排序的效果对当前线程不可见。例如,这就是为什么C中存在volatile
。在.NET中,是JIT实现了这一点,尽管没有其他一些语言那么多。@rytisk:例如,请参见以下答案:Quote:“允许C#编译器和CLR jitter进行大量优化,假设当前线程是唯一正在运行的线程。”谢谢你的回答。学习新的“工具”总是很棒的。我正在研究这些Thread.Sleep()
这很有效。但是这种方法有什么限制吗?任何情况下,我都不应该使用这些。这是一些其他问题的正常指示,但它本身并没有什么问题。当然,你的线程在这段时间内会失去响应,因此如果它是一个UI线程,例如,你的UI将冻结。我会提到任务。延迟比线程。睡眠,因为它可能更适合编写UI,就像这里的情况一样。@JonasH我没有看到任何人提到这是一个UI应用程序?如果OP没有对async/await进行适当的介绍,那么将它扔给他们将不会有帮助。因为他们不知道Thread.Sleep,所以我假设他们可能不熟悉async/await
await Task.Delay(1000);