5

In a single-threaded console application, people often use Thread.Sleep as a lazy way to pause the application for some time.

This question raised interesting points about NOT using this approach: Why is Thread.Sleep so harmful

However other than knowing that Sleep blocks the current thread, I don't understand how it works - for instance does it max out the CPU core in a tight loop or does it actually pause the thread?

More importantly to me, how does a console app respond to various app-exit scenarios (CTRL-C, kill, window close button) when caught in the middle of a Sleep? Will it blindly continue executing until the OS force-kills it, or will it behave well?

Community
  • 1
  • 1
Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • 4
    It simply tells the operating system's thread scheduler to not reschedule the thread for execution for the specified amount of time. So sure, it is "paused". Console kills are implemented by the OS and simply terminate the process. Whatever the threads in the process are doing is not relevant, they cease to be, Norwegian parrot-style. – Hans Passant Jun 06 '16 at 16:57
  • 1
    For those interested, you can see the [implementation for `Thread.Sleep()` here](http://referencesource.microsoft.com/#mscorlib/system/threading/thread.cs,5f1072b92dae1dd8). – Rion Williams Jun 06 '16 at 16:58
  • Thanks @HansPassant 'suspended' is the term I wanted - as Sheeo explicitly points out the thread is suspended rather than leading to spin-lock. Nice MP reference. – Mr. Boy Jun 06 '16 at 17:03
  • Hmm, no, that's not the term you wanted. A suspended thread doesn't have anything to do with Sleep(). But then again anybody that uses SuspendThread() deserves all the misery they'll get. – Hans Passant Jun 06 '16 at 17:10
  • Now I'm confused @HansPassant because the documentation of `Sleep` says "**Sleep** function - **Suspends** the execution of the current thread until the time-out interval elapses" (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx) Would you mind clarifying this in an answer? – Mr. Boy Jun 06 '16 at 17:15

2 Answers2

5

This is more of an OS question than a C#/.NET related question, but I'll try and answer succinctly.

Thread.Sleep will not spin lock your CPU, instead it will call the appropriate mechanism in the underlying OS to suspend your thread. On windows, that function is described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx

Using this normal system call your thread cannot be rescheduled until the timeout has elapsed. Forcefully killing the thread (or the entire process) is then required.

When you hit ctrl+c in cmd.exe, the console spawns a new thread in each process attached to handle the event (Described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682541(v=vs.85).aspx). Because of this, your program as a whole will still "behave well" when you hit ctrl+c, but your sleeping thread itself will wind up being killed prematurely.

Michael Sondergaard
  • 1,464
  • 10
  • 25
2

This is source code of Thread.Sleep method:

[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();
}

As we can see this method calls Thread.SleepInternal method. In comment about it we can read that this method suspends the current thread for timeout milliseconds. Next, we can read that if timeout == 0 then this method forces the thread to give up the remainder of its timeslice and if timeout equals Timeout.Infinite then no timeout will occur. I recommend you reading about multithreading and application lifecycle (in this case especially suspended).

Links:

hubot
  • 393
  • 5
  • 18