将当前线程置于休眠状态

Hos*_*146 13 c# multithreading

我有一个工作单元,我在一个线程(不是主线程).在某些情况下,我想让这个线程睡10秒钟.Thread.Sleep(10000)是最有效的方法吗?

Hen*_*man 21

Thread.Sleep(10000)是最有效的方法吗?

是的,因为它没有忙等待而是放弃了CPU.

但它浪费了一个线程.你不应该将它扩展到许多睡眠线程.

  • ...并注意在C#5中,使用`await Task.Yield` ...包括取消,放弃当前线程10秒就变得非常容易了. (6认同)
  • @MartinJames:你没有找到合适的资源.CPU无关紧要; 1000个休眠线程占用了十亿字节的地址空间(当然,分布在许多进程中).如果它是一个.NET线程,则**该地址空间实际上已提交给页面文件**. (6认同)
  • @Martin:.NET 线程立即消耗 1 MB 的堆栈空间。您看到的 1000 个线程来自不同的进程,其中许多线程将通过较小的堆栈进行非托管。您通常无法在 .NET 应用程序中创建 1k 线程。几百个就很多了。 (2认同)
  • 显然,你现在必须在7月份与Penny Arcade漫画的链接中说"07".http://www.penny-arcade.com/comic/2002/07/22; ^) (2认同)

Jon*_*eet 13

没有人提到它......

如果你想让另一个线程能够唤醒你的"休眠"线程,你可能想要使用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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们只shouldStop在锁内访问,因此没有任何内存模型问题.

可能想要循环等待,直到你真的睡了10秒钟,以防万一你得到虚假的叫醒 - 这取决于你不再做10秒的工作是多么重要.(我从来没有故意听到过虚假的醒来,但我相信它们是可能的.)


adr*_*anm 6

养成使用Thread.CurrentThread.Join(timeout)而不是Thread.Sleep 的习惯.

不同之处在于Join仍然会进行一些消息传递(例如GUI和COM).

大多数情况下它并不重要,但如果您需要在应用程序中使用某些COM或GUI对象,它会让生活更轻松.