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?
Sleep blocks all execution, but only in the thread from which you call it.
Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution. One thread cannot call Thread.
Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.
Every time we deliberately change a thread's status or attributes (e.g. by sleeping, waiting on an object, changing the thread's priority etc), we will cause a context switch.
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With