C# 是 Thread.Sleep(Timeout.Infinite); 比 while(true){} 更有效率?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/13406435/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?
提问by Lunyx
I have a console application that I would like to keep open all of the time while still listening in to events. I have tested Thread.Sleep(Timeout.Infinite);and while (true) { }and both allow the events to be raised while keeping the console application open. Is there one that I should be using over the other? If the thread is sleeping, is there anything that I should not be doing, such as modifying a static collection declared in the scope of the class?
我有一个控制台应用程序,我想在监听事件的同时一直保持打开状态。我已经测试过Thread.Sleep(Timeout.Infinite);并且while (true) { }都允许在保持控制台应用程序打开的同时引发事件。有没有我应该使用的?如果线程正在休眠,是否有什么我不应该做的事情,例如修改在类范围内声明的静态集合?
采纳答案by Reed Copsey
I would recommend using a ManualResetEvent(or other WaitHandle), and calling ManualResetEvent.WaitOne.
我建议使用ManualResetEvent(或其他WaitHandle),并调用ManualResetEvent.WaitOne。
This will have a similar effect to sleeping forever, except that it provides you a clean way to exitfrom your infinite "block" when desired (by calling Set()on the event).
这将具有与永远休眠类似的效果,但它为您提供了一种在需要时退出无限“块”的干净方式(通过调用Set()事件)。
Using while(true)will consume CPU cycles, so it's definitely something to avoid.
使用while(true)会消耗 CPU 周期,因此绝对需要避免。
is there anything that I should not be doing, such as modifying a static collection declared in the scope of the class?
有什么我不应该做的事情,例如修改在类范围内声明的静态集合?
In general, no. Since your thread will be blocked, there shouldn't be any synchronization issues with using shared data (provided the items within the collection don't have specific requirements, such as user interface elements which must be used on a thread with a proper synchronization context.)
一般来说,没有。由于您的线程将被阻塞,因此使用共享数据不应该有任何同步问题(前提是集合中的项目没有特定要求,例如必须在具有适当同步上下文的线程上使用的用户界面元素.)
回答by dasblinkenlight
Unlike while(true)..., Thread.Sleepdoes not use CPU cycles, so in this sense, the sleep is more efficient. In general, using Busy Waitingoutside of spinlocksis strongly discouraged.
与while(true)...,Thread.Sleep不使用 CPU 周期,因此从这个意义上讲,睡眠更有效。通常,强烈建议不要在自旋锁之外使用Busy Waiting。
If the thread is sleeping, is there anything that I should not be doing?
如果线程正在休眠,有什么我不应该做的吗?
Since your thread is blocked upon entry to Thread.Sleep, anything that you wish to do to its resources is a fair game.
由于您的线程在进入 时被阻塞Thread.Sleep,因此您希望对其资源执行的任何操作都是公平的。
回答by Grijesh Chauhan
Yes, 
while(true)consumes CPU while sleep()works in a smarter way: 
The sleep()function puts the current execution context to sleep; it does this by calling a syscall to invoke the kernel sleep function which atomically
(a) sets a wake-up timer
(b) marks the current process as sleeping
(c) waits until the wakeup-timer fires or an interrupt occurs  
是的, 
在以更智能的方式工作的while(true)同时消耗 CPU sleep():该sleep()函数将当前执行上下文置于睡眠状态;它通过调用系统调用来调用内核睡眠函数来实现这一点,该函数原子地
(a) 设置唤醒计时器
(b) 将当前进程标记为睡眠
(c) 等待唤醒计时器触发或中断发生  
If you call sleep(), the CPU can do other work.    
如果调用sleep(),CPU 可以做其他工作。    
That's one reason why sleep()is useful. 
这sleep()就是有用的原因之一。
A useful link - Be careful when using Sleep
一个有用的链接 -使用 Sleep 时要小心
回答by leoismyname
I think the call
我认为电话
while (true) { ... } 
is computationally intensive, since the thread never stops, wheareas
是计算密集型的,因为线程永远不会停止,所以
Thread.Sleep(Timeout.Infinite);
actually gets the thread to sleep with help of OS native schedulers. And then the thread actually stops, so I suppose it's less computationally demanding.
实际上在操作系统本机调度程序的帮助下让线程进入睡眠状态。然后线程实际上停止了,所以我认为它的计算要求较低。
回答by Alberto
Calling the Thread.Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread.
调用 Thread.Sleep 方法会导致当前线程在传递给该方法的毫秒数或时间间隔内立即阻塞,并将其时间片的剩余部分交给另一个线程。
https://msdn.microsoft.com/en-us/library/tttdef8x(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/tttdef8x(v=vs.110).aspx
回答by Vinigas
Since C# 7.1you can make Mainmethod asynchronous. That means instead of using busy-wait or thread-locking sleeping, you can suspend Mainmethod asynchronously as a Task. This way thread which runned Mainwill not be locked. And with Cts.Cancel();you can easily release main-task to exit application (without allowing to finish work for other threads/tasks).
从C# 7.1 开始,您可以使Main方法异步。这意味着您可以将Main方法作为Task异步挂起,而不是使用忙等待或线程锁定睡眠。这样运行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);
}

