是Thread.Sleep(Timeout.Infinite);比while(true){}效率更高?

时间:2012-11-15 21:21:34

标签: c# console-application

我有一个控制台应用程序,我希望在仍然收听事件的同时保持打开状态。我测试了Thread.Sleep(Timeout.Infinite);while (true) { },并且都允许在保持控制台应用程序打开的同时引发事件。我应该使用另一个吗?如果线程正在休眠,是否有任何我不应该做的事情,比如修改在类范围内声明的静态集合?

6 个答案:

答案 0 :(得分:28)

我建议您使用ManualResetEvent(或其他WaitHandle)并致电ManualResetEvent.WaitOne

这将永远与睡眠有类似的效果,除了它为您提供了一个干净的方式来从您的无限“块”中退出(通过在事件上调用Set()

使用while(true)将消耗CPU周期,因此绝对应该避免。

  

有什么我不应该做的,比如修改在类范围内声明的静态集合吗?

一般来说,没有。由于您的线程将被阻止,因此使用共享数据时不应存在任何同步问题(前提是集合中的项目没有特定要求,例如必须在具有适当同步上下文的线程上使用的用户界面元素。)

答案 1 :(得分:4)

while(true)...不同,Thread.Sleep不使用CPU周期,因此从这个意义上讲,睡眠效率更高。一般情况下,强烈建议不要在Busy Waiting之外使用spinlocks

  

如果线程正在睡眠,那么我有什么不该做的吗?

由于你的帖子在进入Thread.Sleep后被阻止,你想对其资源做的任何事都是公平的游戏。

答案 2 :(得分:4)

我认为电话

while (true) { ... } 

是计算密集型的,因为线程永远不会停止,wheareas

Thread.Sleep(Timeout.Infinite);

实际上是在OS本机调度程序的帮助下让线程进入休眠状态。然后线程实际上停止了,所以我认为它的计算要求不高。

答案 3 :(得分:2)

下, while(true)消耗CPU,而sleep()以更智能的方式工作: sleep()函数将当前执行上下文置于休眠状态;它通过调用一个系统调用来调用内核休眠函数来实现这一点 (a)设置唤醒计时器
(b)将目前的程序标记为睡觉 (c)等到唤醒定时器触发或发生中断

如果您致电sleep(),CPU可以执行其他工作。

这是sleep()有用的原因之一。

一个有用的链接 - Be careful when using Sleep

答案 4 :(得分:1)

由于 C#7.1 ,您可以使 Main 方法异步。这意味着您可以使用 Task 异步地暂停 Main 方法,而不是使用忙碌等待或线程锁定睡眠。这样,运行 Main 的线程将不会被锁定。借助Cts.Cancel();,您可以轻松地释放主任务以退出应用程序(而无需完成其他线程/任务的工作)。

static readonly CancellationTokenSource Cts = new CancellationTokenSource();
static async Task Main(string[] args)
{
    /* your code here */

    await Task.Delay(Timeout.Infinite, Cts.Token);
}

答案 5 :(得分:0)

  

调用Thread.Sleep方法会导致当前线程立即阻塞毫秒数或传递给方法的时间间隔,并将其时间片的剩余时间转换为另一个线程。

https://msdn.microsoft.com/en-us/library/tttdef8x(v=vs.110).aspx