[c#] How do I get my C# program to sleep for 50 msec?

How do I get my C# program to sleep for 50 milliseconds?

This might seem an easy question, but I'm having a temporary brain failure moment!

This question is related to c# vb.net

The answer is


Thread.Sleep(50);

The thread will not be scheduled for execution by the operating system for the amount of time specified. This method changes the state of the thread to include WaitSleepJoin.

This method does not perform standard COM and SendMessage pumping. If you need to sleep on a thread that has STAThreadAttribute, but you want to perform standard COM and SendMessage pumping, consider using one of the overloads of the Join method that specifies a timeout interval.

Thread.Join

Use this code

using System.Threading;
// ...
Thread.Sleep(50);

Thread.Sleep(50);

The thread will not be scheduled for execution by the operating system for the amount of time specified. This method changes the state of the thread to include WaitSleepJoin.

This method does not perform standard COM and SendMessage pumping. If you need to sleep on a thread that has STAThreadAttribute, but you want to perform standard COM and SendMessage pumping, consider using one of the overloads of the Join method that specifies a timeout interval.

Thread.Join

Starting with .NET Framework 4.5, you can use:

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms

Since now you have async/await feature, the best way to sleep for 50ms is by using Task.Delay:

async void foo()
{
    // something
    await Task.Delay(50);
}

Or if you are targeting .NET 4 (with Async CTP 3 for VS2010 or Microsoft.Bcl.Async), you must use:

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

This way you won't block UI thread.


Use this code

using System.Threading;
// ...
Thread.Sleep(50);

Best of both worlds:

using System.Runtime.InteropServices;

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    private static extern uint TimeBeginPeriod(uint uMilliseconds);

    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    private static extern uint TimeEndPeriod(uint uMilliseconds);
    /**
     * Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
     */
    private void accurateSleep(int milliseconds)
    {
        //Increase timer resolution from 20 miliseconds to 1 milisecond
        TimeBeginPeriod(1);
        Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
        stopwatch.Start();

        while (stopwatch.ElapsedMilliseconds < milliseconds)
        {
            //So we don't burn cpu cycles
            if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
            {
                Thread.Sleep(5);
            }
            else
            {
                Thread.Sleep(1);
            }
        }

        stopwatch.Stop();
        //Set it back to normal.
        TimeEndPeriod(1);
    }

You can't specify an exact sleep time in Windows. You need a real-time OS for that. The best you can do is specify a minimum sleep time. Then it's up to the scheduler to wake up your thread after that. And never call .Sleep() on the GUI thread.


There are basically 3 choices for waiting in (almost) any programming language:

  1. Loose waiting
    • Executing thread blocks for given time (= does not consume processing power)
    • No processing is possible on blocked/waiting thread
    • Not so precise
  2. Tight waiting (also called tight loop)
    • processor is VERY busy for the entire waiting interval (in fact, it usually consumes 100% of one core's processing time)
    • Some actions can be performed while waiting
    • Very precise
  3. Combination of previous 2
    • It usually combines processing efficiency of 1. and preciseness + ability to do something of 2.

for 1. - Loose waiting in C#:

Thread.Sleep(numberOfMilliseconds);

However, windows thread scheduler causes acccuracy of Sleep() to be around 15ms (so Sleep can easily wait for 20ms, even if scheduled to wait just for 1ms).

for 2. - Tight waiting in C# is:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

We could also use DateTime.Now or other means of time measurement, but Stopwatch is much faster (and this would really become visible in tight loop).

for 3. - Combination:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do STILL POSSIBLE
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
    Thread.Sleep(1); //so processor can rest for a while
}

This code regularly blocks thread for 1ms (or slightly more, depending on OS thread scheduling), so processor is not busy for that time of blocking and code does not consume 100% of processor's power. Other processing can still be performed in-between blocking (such as: updating of UI, handling of events or doing interaction/communication stuff).


Since now you have async/await feature, the best way to sleep for 50ms is by using Task.Delay:

async void foo()
{
    // something
    await Task.Delay(50);
}

Or if you are targeting .NET 4 (with Async CTP 3 for VS2010 or Microsoft.Bcl.Async), you must use:

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

This way you won't block UI thread.


There are basically 3 choices for waiting in (almost) any programming language:

  1. Loose waiting
    • Executing thread blocks for given time (= does not consume processing power)
    • No processing is possible on blocked/waiting thread
    • Not so precise
  2. Tight waiting (also called tight loop)
    • processor is VERY busy for the entire waiting interval (in fact, it usually consumes 100% of one core's processing time)
    • Some actions can be performed while waiting
    • Very precise
  3. Combination of previous 2
    • It usually combines processing efficiency of 1. and preciseness + ability to do something of 2.

for 1. - Loose waiting in C#:

Thread.Sleep(numberOfMilliseconds);

However, windows thread scheduler causes acccuracy of Sleep() to be around 15ms (so Sleep can easily wait for 20ms, even if scheduled to wait just for 1ms).

for 2. - Tight waiting in C# is:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

We could also use DateTime.Now or other means of time measurement, but Stopwatch is much faster (and this would really become visible in tight loop).

for 3. - Combination:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do STILL POSSIBLE
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
    Thread.Sleep(1); //so processor can rest for a while
}

This code regularly blocks thread for 1ms (or slightly more, depending on OS thread scheduling), so processor is not busy for that time of blocking and code does not consume 100% of processor's power. Other processing can still be performed in-between blocking (such as: updating of UI, handling of events or doing interaction/communication stuff).


Thread.Sleep(50);

The thread will not be scheduled for execution by the operating system for the amount of time specified. This method changes the state of the thread to include WaitSleepJoin.

This method does not perform standard COM and SendMessage pumping. If you need to sleep on a thread that has STAThreadAttribute, but you want to perform standard COM and SendMessage pumping, consider using one of the overloads of the Join method that specifies a timeout interval.

Thread.Join

Starting with .NET Framework 4.5, you can use:

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms

Thread.Sleep(50);

The thread will not be scheduled for execution by the operating system for the amount of time specified. This method changes the state of the thread to include WaitSleepJoin.

This method does not perform standard COM and SendMessage pumping. If you need to sleep on a thread that has STAThreadAttribute, but you want to perform standard COM and SendMessage pumping, consider using one of the overloads of the Join method that specifies a timeout interval.

Thread.Join

Use this code

using System.Threading;
// ...
Thread.Sleep(50);

Best of both worlds:

using System.Runtime.InteropServices;

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    private static extern uint TimeBeginPeriod(uint uMilliseconds);

    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    private static extern uint TimeEndPeriod(uint uMilliseconds);
    /**
     * Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
     */
    private void accurateSleep(int milliseconds)
    {
        //Increase timer resolution from 20 miliseconds to 1 milisecond
        TimeBeginPeriod(1);
        Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
        stopwatch.Start();

        while (stopwatch.ElapsedMilliseconds < milliseconds)
        {
            //So we don't burn cpu cycles
            if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
            {
                Thread.Sleep(5);
            }
            else
            {
                Thread.Sleep(1);
            }
        }

        stopwatch.Stop();
        //Set it back to normal.
        TimeEndPeriod(1);
    }

You can't specify an exact sleep time in Windows. You need a real-time OS for that. The best you can do is specify a minimum sleep time. Then it's up to the scheduler to wake up your thread after that. And never call .Sleep() on the GUI thread.


For readability:

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));

You can't specify an exact sleep time in Windows. You need a real-time OS for that. The best you can do is specify a minimum sleep time. Then it's up to the scheduler to wake up your thread after that. And never call .Sleep() on the GUI thread.


For readability:

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));