Sleep会阻止程序退出吗?它是如何实现的?

时间:2016-06-06 16:47:49

标签: c# .net multithreading thread-sleep

在单线程控制台应用程序中,人们经常使用Thread.Sleep作为暂停应用程序一段时间的懒惰方式。

这个问题提出了一些关于不使用这种方法的有趣观点:Why is Thread.Sleep so harmful

然而,除了知道Sleep阻止当前线程之外,我不明白它是如何工作的 - 例如它是否在紧密循环中最大化CPU内核还是实际上暂停了线程?

对我来说更重要的是,控制台应用程序如何在睡眠中被捕获时响应各种应用程序退出方案(CTRL-C,kill,窗口关闭按钮)?它会盲目地继续执行,直到操作系统强行杀死它,还是表现良好?

2 个答案:

答案 0 :(得分:5)

这更像是一个操作系统问题,而不是与C#/ .NET相关的问题,但我会尝试简洁地回答。

Thread.Sleep不会自动锁定你的CPU,而是会调用底层操作系统中的相应机制来暂停你的线程。在Windows上,此功能在此处描述:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx

使用此正常系统调用,在超时结束之前,无法重新调度您的线程。然后需要强制终止线程(或整个过程)。

当您在cmd.exe中按ctrl + c时,控制台会在附加的每个进程中生成一个新线程来处理事件(在此处描述:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682541(v=vs.85).aspx)。因此,当你按下ctrl + c时,整个程序仍然会“表现得很好”,但是你的睡眠线程本身会被过早杀死。

答案 1 :(得分:2)

这是 Thread.Sleep 方法的源代码:

[System.Security.SecuritySafeCritical]  // auto-generated
public static void Sleep(int millisecondsTimeout)
{
    SleepInternal(millisecondsTimeout);
    // Ensure we don't return to app code when the pause is underway
    if(AppDomainPauseManager.IsPaused)
        AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
}

我们可以看到此方法调用 Thread.SleepInternal 方法。在评论它我们可以读到这个方法暂停当前线程的超时毫秒。接下来,我们可以读取如果timeout == 0则此方法强制线程放弃其时间片的剩余部分,如果超时等于Timeout.Infinite,则不会发生超时。我建议您阅读多线程和应用程序生命周期(在这种情况下特别是暂停)。

链接: