Posts By Category

Posts By Date

Resources:

C# Books
ASP.NET Books DotNet4All








If you like to support this site, feel free to make a donation to support improvements.

Thank you!

Monetize Your Blog

Use Intermittent Sleeping (small increments) instead of one long Thread.Sleep for a quicker, more responsive multi-threaded application

We all had to use Thread.Sleep at one point or another to wait on an event to happen, or to satisfy a configuration setting during cyclic calculations or a processing. But is your worker thread sleeping too much? Does it feel sometimes that your code sleeps in the wrong time

increments when it shouldn’t be? Making your “Multi-Threaded” C# software not as responsive as you hoped it would be?

 

One possible reaosn that can cause this to happen is the improper usage of Thread.Sleep calls. The problem is that sleeping for a long interval can sometimes lead to less responsive applications. For example, suppose you have a worker thread which wakes up every 1 minute, processes some data, then goes back to sleep. Here is how its event loop might look like:

 

int cycleSleepTime=60000;  // or load from config

volatile bool _bStop= false ;

 

// Worker Thread Processing loop

while (!_bStop)

{

    // Process Data Here

    // ...

 

    // Sleep for a minute

    System.Threading. Thread .Sleep(cycleSleepTime);

}

 

If you wanted to stop the worker thread from the main thread, you’d set the volatile member _bStop to true which puts a condition that causes the processing loop to exit the next time it executes:

 

// From Main Thread: Request the worker thread to stop

_bStop=true;

 

What’s the problem with the above implementation? Well, suppose that cycleSleepTime was a configurable variable, and your user decided to increase it to say, every 10 minutes. Since the worker thread’s event loop processes every thing, including stop requests only when it wakes up, it might take it up to 10 minutes before it honors the main thread’s request to stop processing. Suppose you displayed the processing status in a multi-threaded GUI application. Waiting 10 minutes to stop something from the GUI before it actually stops is a long time, and would render your “multi-threaded” application sloppy and unresponsive, even though you are using threads and all the good stuff.

 

So what’s the alternative? The answer is to separate processing important requests (like the stop request) from the rest of the worker’s thread loop. One way to achieve that is to sleep intermittently for small periods of time to stay responsive to important messages and events.

 

The following method can be used in place of the Thread.Sleep:

 

public void SleepIntermittently(int totalTime)

{

    int sleptTime = 0;

    int intermittentSleepIncrement = 10;

     // Wake up every 10 milli-seconds too check if we need

    // to stop or not

    while (!_bStop && sleptTime < totalTime)

    {

        Thread.Sleep(intermittentSleepIncrement);

        sleptTime += intermittentSleepIncrement;

    }

}

 

Now in the worker’s thread, all we have to do is make the following small change:

 

int cycleSleepTime=60000;  // or load from config

volatile bool _bStop=false;

 

// Worker Thread Processing loop

while (!_bStop)

{

    // Process Data Here

    // ...

 

    // Sleep for a minute

    SleepIntermittently(cycleSleepTime);

}

 

Now when the main thread requests to stop the worker’s thread, the response can come back within 10 milliseconds (a big performance gain compared to up to 10 minutes before), no matter what the cycleSleepTime happens to be, and the user can change it freely from the configuration file without affecting how the application responds to the user’s important commands. Definitely a better design!

kick it on DotNetKicks.com

Feedback

Posted on 10/16/2009 5:55:19 AM

Why don't you use Monitor.Wait and Pulse? You would be able to achieve your aim much more efficiently.

Posted on 7/29/2009 10:14:20 AM

"Houston WebDesign" does make a good point. Does IIS still handle requests if one request has used Thread.Sleep()? Would all the requests get queued up? I will test it and see if it does.

Posted on 4/21/2009 10:44:28 PM

I was wondering, for those of us who are using a Single Worker Process in IIS 6.0. If I had a Thread.Sleep in my code, will IIS continue to handle requests for other users? Or will my queue backup until my sleep time finishes?

Posted on 11/18/2008 2:32:16 PM

Thats pretty poor code either way, use of events to trigger actions and timers can avoid that completely.

See Microsoft's producer-consumer example - http://msdn.microsoft.com/en-us/library/yy12yx1f(VS.80).aspx

public void ThreadRun()
{
int count = 0;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
{
lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < 20)
{
_queue.Enqueue(r.Next(0,100));
_syncEvents.NewItemEvent.Set();
count++;
}
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}

One event signals the thread should work, another signals it to stop.

Posted on 7/9/2008 5:58:21 PM

Sometimes you want only a single thread operating. We needed to setup a database "listener" and absolutely did not want multiple threads in operation at the same time.

Posted on 4/28/2007 3:05:55 AM

Doesn't it make more sense to use a timer on your worker thread and set the timer to go off every so many seconds, then you do the processing you want to do on the timer tick? This way the thread is still free to do other things the whole time, then you don't even have to sleep at all.

John

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Enter the text you see in the box:
 


Copyright © 2007 Yousef Mannaa. All material on this site is copyrighted.
Do not publish or reproduce any of this material without written permission from the Author