I have a unit of work I'm doing in a thread (not the main thread). Under certain circumstances I would like to put this thread to sleep for 10 seconds. Is Thread.Sleep(10000) the most resource efficient way to do this?
-
How do you both conclude that? Does the efficiency of putting a thread to sleep only apply to homework? How about to people learning on their own? – MGZero Oct 04 '11 at 16:25
-
5You sure you want to sleep the thread? That's a bad code smell right there. First off, while it is sleeping the thread is not responding to events coming to it from other threads. Second, ten seconds is like forty **billion** processor cycles. You really want to be wasting *an entire thread* for forty billion processor cycles? Couldn't it be doing something else in that time? – Eric Lippert Oct 04 '11 at 17:02
-
It's quite reasonable to sleep() for ten seconds. If the requirement spec says 'do nothing for 10 seconds', then why not. This is not an unusual requirement either, eg. process control: 'turn on motor to close hot water valve B, wait 10 seconds, check flow rate, if not zero signal an alarm'. – Martin James Oct 04 '11 at 17:58
-
6@MartinJames: In that scenario, why spend resources on an entire thread? I would do the work on the main thread; when you have to wait, set a timer and then keep on doing work on the main thread as work comes in. Eventually the timer will go off and the main thread will continue to do the work. **Threads are extremely heavy** in .NET -- whenever I see a thread made to sit idle I worry. You allocated that thread -- with its million bytes of address space -- to do work, so keep it working. – Eric Lippert Oct 04 '11 at 18:08
-
2You'll note that this is how the "Delay" feature works in the async CTP. The current thread is not put to sleep; it keeps on doing work. When the delay time is up, the continuation of the delay is enqueued onto the thread's work queue. You get the desired delay without burning an entire thread that is then sitting there doing nothing. – Eric Lippert Oct 04 '11 at 18:15
-
2@Martin James: Are you doing that in firmware? I work on the software side of process control, and I guarantee that if I see a sleep used in that manner, it's getting flagged as a problem. – Greg D Oct 05 '11 at 13:54
-
@EricLippert pardon my ignorance: `Second, ten seconds is like forty billion processor cycles. You really want to be wasting an entire thread for forty billion processor cycles?`. I was under impression that blocked thread relinquishes its CPU time slice(i.e. uses no CPU cycles), and CPU is given to other threads. Why 40bn cycles are wasted ? – newprint Oct 07 '14 at 18:31
-
3@newprint: You have two cars and three drivers. Two of the drivers are constantly fighting over who gets to use one of the cars. Your statement is "if I pay one of those drivers to sleep on the job then they'll stop fighting over who gets to use the car". **But you're paying a driver to sleep on the job**. That's the problem! If you only have enough work for two drivers to do then *only pay for two drivers and give them each a car*. If you have enough work for three drivers to do then *buy a third car*. But paying an expensive driver to sleep for a year is a waste of resources. – Eric Lippert Oct 07 '14 at 19:05
-
1@newprint: You're welcome. The takeaways here is that threads are scarce and expensive resources; treat threads the way you'd treat an employee. You don't hire an employee unless you have a *lot* of work for them to do and you can afford to pay their salary. If you have a variable amount of work to do, don't put threads to sleep. Do some portion of the work, put the thread back in the thread pool so that it can be assigned another task, and if you have to make a delay, *use a timer* to schedule more work in the future on the pool. `Task.Delay` does so efficiently. – Eric Lippert Oct 07 '14 at 20:01
6 Answers
Is Thread.Sleep(10000) the most resource efficient way to do this?
Yes in the sense that it is not busy-waiting but giving up the CPU.
But it is wasting a Thread. You shouldn't scale this to many sleeping threads.

- 263,252
- 30
- 330
- 514
-
7... and note that in C# 5 it becomes really easy to give up your current thread for 10 seconds, using `await Task.Yield`... including with cancellation. – Jon Skeet Oct 04 '11 at 16:41
-
How many many sleeping threads is too many? As I write this, my box has 1007 threads and 2% CPU usage. Obviously, nearly all those threads are blocked on something, probably sleeping or blocked on something with a timeout, (and so are in the OS timeout queue as well). Doesn't seem to be affecting performance much.. – Martin James Oct 04 '11 at 18:04
-
2@Martin: A .NET thread immediately consumes 1 MB for the stack. The 1000 threads you see are from different processes and many will be unmanaged with smaller stacks. You generally won't be able to create 1k threads in a .NET app. A few hundreds is a lot. – H H Oct 04 '11 at 18:08
-
6@MartinJames: You're not looking at the right resource. CPU is irrelevant; 1000 sleeping threads consume a billion bytes of address space (spread across however many processes, of course). If it is a .NET thread then **that address space is actually committed to the page file**. – Eric Lippert Oct 04 '11 at 18:10
-
@EricLippert etc. Oh - another reason to not like .NET
An awful lot of my 1000-odd threads seem to belong to the OS and M$ supplied apps - thank the lord that M$ does not use .NET for its own stuff, else I'd be swamped! More seriously, though, for a requirement that only needs 3, or 20, asynchronous process flows, a thread for each flow is a reasonable solution and, if the process needs a 10-second wait, then fine, I will sleep(). Main-thread timers, or other such, would be just loads of extra mess for no aparrent gain, (OK, even I would baulk at hundreds of threads, .NET or not). – Martin James Oct 04 '11 at 18:38 -
2Apparently you have to say `07` for July in your links to Penny Arcade comics now. http://www.penny-arcade.com/comic/2002/07/22 ;^) – ruffin Aug 31 '14 at 17:29
As no-one else has mentioned it...
If you want another thread to be able to wake up your "sleeping" thread, you may well want to use Monitor.Wait
instead of 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;
}
}
}
}
Note that we only access shouldStop
within the lock, so there aren't any memory model concerns.
You may want to loop round waiting until you've really slept for 10 seconds, just in case you get spurious wake-ups - it depends on how important it is that you don't do the work again for another 10 seconds. (I've never knowingly encountered spurious wakes, but I believe they're possible.)

- 1,421,763
- 867
- 9,128
- 9,194
-
1Or why not use [ManualResetEvent](http://msdn.microsoft.com/en-us/library/cc189907.aspx)? Similar but shorter in code... – erikH Oct 04 '11 at 16:38
-
@erikH: I generally use the CLR lock constructs unless I really *need* a Win32 event for some reason. – Jon Skeet Oct 04 '11 at 16:40
-
-
It is certainly interesting to read, as it's semi-inconsistent as far as readability (it may not be obvious to all, especially to me at the time) by mixing a statement and static class methods, but after reading [Monitor vs lock](http://stackoverflow.com/questions/4978850/monitor-vs-lock) I certainly understand your comment. – Erik Philips Nov 05 '14 at 17:20
-
@Erik: Not at all sure what you mean about being "semi-inconsistent". It's just syntactic sugar, like foreach and using. The fact that it calls a static method is neither here nor there, IMO. – Jon Skeet Nov 05 '14 at 17:22
-
1@Jon just from readability. Saying `lock` then call a static method `Monitor.Wait()` is (definitely nitpicking here) inconsistent, but from a functional point of view is obviously superior. Basically I'm saying you could have used `Monitor.Enter()` and all locking would be consistently readable (in my eyes) but for obviously good reasons (that I appreciate) you didn't. – Erik Philips Nov 05 '14 at 17:27
Make a habit of using Thread.CurrentThread.Join(timeout) instead of Thread.Sleep.
The difference is that Join will still do some message pumping (e.g. GUI & COM).
Most of the time it doesn't matter but it makes life easier if you ever need to use some COM or GUI object in your application.

- 14,468
- 5
- 55
- 102
This will process something every x seconds without using a thread Not sure how not using your own thread compares with a task to run that is created every two seconds
public void LogProcessor()
{
if (_isRunning)
{
WriteNewLogsToDisk();
// Come back in 2 seonds
var t = Task.Run(async delegate
{
await Task.Delay(2000);
LogProcessor();
});
}
}

- 3,463
- 17
- 18
From resource efficiency, yes.
For design, it depends on the circumstances for the pause. You want your work to be autonomous so if the thread has to pause because it knows to wait then put the pause in the thread code using the static Thread.Sleep method. If the pause happens because of some other external event than you need to control the thread processing, then have the thread owner keep reference to the thread and call childThread.Sleep.

- 191
- 1
- 5
Yes. There's no other efficient or safe way to sleep the thread.
However, if you're doing some work in a loop, you may want to use Sleep in loop to make aborting the thread easier, in case you want to cancel your work.
Here's an example:
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++; }
}
}

- 27,674
- 12
- 80
- 107
-
Just to note, exit should be a global variable viewable from everywhere, and you can just set it to true to exit the thread. Obviously there's other things to take into account. You should NEVER use Sleep in a UI thread, for example. – Polynomial Oct 04 '11 at 16:31
-
1Using `Monitor.Wait` here would be more efficient - you can wait for 10 seconds, and if something wants to wake you up to tell you to exit, they can pulse the monitor. – Jon Skeet Oct 04 '11 at 16:32
-
(I'd also question the "there's no other efficient or safe way to sleep a thread" claim, given my answer...) – Jon Skeet Oct 04 '11 at 16:41
-
You will have to declare exit as volatile or use some other way to prevent it being cached. – H H Oct 04 '11 at 17:09
-
Jon - Thanks for the info, I hadn't thought of doing it that way. I'll refactor my existing projects to use that instead. – Polynomial Oct 04 '11 at 21:13