我有一个在线程中(非主线程)执行的工作单元。在某些情况下,我想让该线程休眠10秒钟。Thread.Sleep(10000)是最节约资源的方法吗?
我有一个在线程中(非主线程)执行的工作单元。在某些情况下,我想让该线程休眠10秒钟。Thread.Sleep(10000)是最节约资源的方法吗?
Thread.Sleep(10000)是最节约资源的方法吗?
从不忙等待而是让出CPU的角度来看,确实是最节约资源的。
但这种方式会浪费一个线程。如果有很多休眠线程,就不应采用此方法进行扩展。
await Task.Yield
可以轻松放弃当前线程10秒钟,包括取消操作。 - Jon Skeet07
。http://www.penny-arcade.com/comic/2002/07/22 ;^) - ruffin由于没有其他人提到过这一点...
如果你想让另外一个线程能够唤醒你的“睡眠”线程,你很可能需要使用 Monitor.Wait
而不是 Thread.Sleep
:
private readonly object sharedMonitor;
private bool shouldStop;
public void Stop()
{
lock (sharedMonitor)
{
shouldStop = true;
Monitor.Pulse(sharedMonitor);
}
}
public void Loop()
{
while (true)
{
// Do some work...
lock (sharedMonitor)
{
if (shouldStop)
{
return;
}
Monitor.Wait(sharedMonitor, 10000);
if (shouldStop)
{
return;
}
}
}
}
注意我们只在锁内部访问shouldStop
,因此没有任何内存模型方面的问题。
你可能希望循环等待,直到你真正休眠了10秒,以防止发生虚假唤醒——这取决于你再次执行工作的间隔时间有多重要。不要再次执行该工作的重要性如何。(我从未知道过虚假唤醒,但我相信它们是可能存在的。)
lock
而不是Monitor.Enter()
的原因是什么? - Erik Philips养成使用Thread.CurrentThread.Join(timeout) 而不是 Thread.Sleep 的习惯。
区别在于 Join 仍会执行一些消息泵(例如GUI和COM)。
大部分情况下这并不重要,但如果你需要在应用程序中使用一些COM或GUI对象,这将使生活更加轻松。
这将每 x 秒处理一些内容,而不使用线程。不确定如何与每两秒创建一个任务的方式相比。
public void LogProcessor()
{
if (_isRunning)
{
WriteNewLogsToDisk();
// Come back in 2 seonds
var t = Task.Run(async delegate
{
await Task.Delay(2000);
LogProcessor();
});
}
}
从资源效率的角度来看,是的。
对于设计而言,取决于暂停的情况。您希望您的工作是自主的,因此如果线程必须暂停,因为它知道要等待,则使用静态Thread.Sleep方法在线程代码中放置暂停。如果暂停发生是由于某些其他外部事件,则需要控制线程处理,然后让线程所有者保留对线程的引用并调用childThread.Sleep。
是的。没有其他有效或安全的方法来使线程休眠。
但是,如果您正在循环中执行某些工作,则可能希望在循环中使用Sleep,以使取消线程更容易,以防您想要取消工作。
以下是一个示例:
bool exit = false;
...
void MyThread()
{
while(!exit)
{
// do your stuff here...
stuff...
// sleep for 10 seconds
int sc = 0;
while(sc < 1000 && !exit) { Thread.Sleep(10); sc++; }
}
}
Monitor.Wait
会更有效率 - 你可以等待10秒钟,如果有什么东西想要唤醒你告诉你退出,它们可以脉冲监视器。 - Jon Skeet