Hosea146
Hosea146

Reputation: 7702

Putting the current thread to sleep

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?

Upvotes: 17

Views: 72615

Answers (6)

IvoTops
IvoTops

Reputation: 3531

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

Upvotes: 1

adrianm
adrianm

Reputation: 14726

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.

Upvotes: 8

Henk Holterman
Henk Holterman

Reputation: 273244

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.

Upvotes: 25

Jon Skeet
Jon Skeet

Reputation: 1500525

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.)

Upvotes: 14

Polynomial
Polynomial

Reputation: 28316

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++; }
    }
}

Upvotes: 0

Steve
Steve

Reputation: 301

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.

Upvotes: 1

Related Questions