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