How to avoid Thread.Sleep in your production code in .NET

Avoiding Thread.Sleep in production code in .NET using C#

I am pretty sure any of us used Thread.Sleep method to pause the current thread execution. Mostly this is used to simulate long running process during the test or debug.

While this is fine to use for testing, if your intention is to actually schedule thread execution this is probably wrong way of doing it, simply because Thread.Sleep does not actually take as many milliseconds as you pass to the method as a parameter. Instead it only guarantees that it will halt the thread for at least that many seconds because it is based on timeslices number which defers for different Windows versions. More about this you can read in article Thread.Sleep is a sign of a poorly designed program.

So OK, Thread.Sleep is a big NO NO, but what can we use instead?

There are few suggestions what can you use to schedule a Thread execution. On the highest level you can use Quartz.NET library, but if you do not require any big logic for scheduling the execution this is a bit an overhead.

One of the things that can be use is System.Threading.AutoResetEvent in combination with System.Timers.Timer class. Tho following is an example of using Timer and AutoResetEvent in an infinite loop, a most common place where Thread.Sleep is used by mistake.

using System;
using System.Threading;
using System.Timers;
namespace NoThreadSleep
{
class Program
{
static System.Timers.Timer timer = new System.Timers.Timer(1000) { AutoReset=true};
static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
static void Main(string[] args)
        {
            timer.Elapsed += Timer_Elapsed;
            timer.Start();

            ThreadPool.QueueUserWorkItem((state) =>
            {
                while (true)
                {
                    Console.WriteLine(DateTime.Now);
                    autoResetEvent.WaitOne();
                }

            });

            Console.ReadLine();

        }

        private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            autoResetEvent.Set();
        }
    }
}

    

Instead of relying to Thread.Sleep slicing we will actually have out Timer setting the event and schedule the Thread execution. Since it is AutoResetEvent instead ManualResetEvent, once the thread executes, we'll have our event reset automatically.

When you run the code above you will get properly printed out time string with interval of 1 second which is the timer interval set

2018-03-26 16:24:36
2018-03-26 16:24:37
2018-03-26 16:24:38
2018-03-26 16:24:39
2018-03-26 16:24:40
2018-03-26 16:24:41
2018-03-26 16:24:42
2018-03-26 16:24:43
2018-03-26 16:24:44
2018-03-26 16:24:45
2018-03-26 16:24:46
2018-03-26 16:24:47
2018-03-26 16:24:48

This is only one of the ways to avoid Thread.Sleep. It is one of the most simpler way of scheduling the Thread execution.

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform including ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN  Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

JavaScript

read more

SQL/T-SQL

read more

Umbraco CMS

read more

PowerShell

read more

Comments for this article