What is the impact of Thread.Sleep(1) in C#?
Asked Answered
B

10

30

In a windows form application what is the impact of calling Thread.Sleep(1) as illustrated in the following code:

public Constructor()
{
    Thread thread = new Thread(Task);
    thread.IsBackground = true;
    thread.Start();
}

private void Task()
{
    while (true)
    {
        // do something
        Thread.Sleep(1);
    }
}

Will this thread hog all of the available CPU?

What profiling techniques can I use to measure this Thread's CPU usage ( other than task manager )?

Brattishing answered 3/2, 2009 at 17:59 Comment(2)
All the answers so far indicate that the effect would be negligible, but can you give some clarification on what you're trying to accomplish with this?Timberland
I'm just trying to see if my GUI application with spend all of its time in this thread because of the short 1ms delay.Brattishing
T
47

As stated, your loop will not hog the CPU.

But beware: Windows is not a real-time OS, so you will not get 1000 wakes per second from Thread.Sleep(1). If you haven't used timeBeginPeriod to set your minimum resolution you'll wake about every 15 ms. Even after you've set the minimum resolution to 1 ms, you'll still only wake up every 3-4 ms.

In order to get millisecond level timer granularity you have to use the Win32 multimedia timer (C# wrapper).

Tobytobye answered 3/2, 2009 at 18:35 Comment(2)
Could you give an example of setting up timeBeginPeriod in C#?Brattishing
pinvoke.net/default.aspx/winmm.timeBeginPeriod According to the MSDN doc, timeBeginPeriod should be matched with a timeEndPeriod call. Also note that "This function affects a global Windows setting." and can affect system performance.Tobytobye
L
28

No it won't hog the CPU, it will just pause your thread for at least that long. While your thread is paused, the operating system can schedule another, unrelated thread to make use of the processor.

Legwork answered 3/2, 2009 at 18:1 Comment(4)
It would hog a LOT of cpu time unnecessarily, though.Tootle
@Joel How/why would it hog more time than a while (true) { i++; } or is it essentially the same in terms of CPU usage?Dioptometer
On a modern CPU a 1ms sleep is an eternity compared to doing i++.Congresswoman
@Joel relative to a 10-function calculator's total available CPU time, yes, that will hog a "LOT" of CPU time. Relative to the available CPU time of any machine manufactured in the past decade, it'll use approximately ZERO CPU time.Aristides
C
21

Thread.Sleep(1) as stated will not hog the CPU.

Here is what happens when a thread sleeps (more or less):

  • Thread.Sleep is translated into a system call, which in turn triggers a trap (an interruption that allows the operating system to take control)
  • The operating system detects the call to sleep and marks your thread as blocked.
  • Internally the OS keeps a list of threads that need to be waken up and when it should happen.
  • Since the thread is no longer using the CPU the OS...
  • If the parent process has not used up all of its time slice the OS will schedule another thread of the process for execution.
  • Otherwise another process (or the idle process) will start executing.
  • When the time is due, your thread will be scheduled again for execution, that doesn't mean it will start executing automatically.

On a final note, I don't exactly know what you are doing but it would seem you're trying to take the role of the scheduler, that is, sleeping to provide the CPU with time to do other things...

In a few cases (very few indeed) it might be all right, but mostly you should let the scheduler do its work, it probably knows more than you do, and can make the work better than you can do it.

Continuance answered 4/2, 2009 at 0:47 Comment(0)
E
6

Small sleep times should be avoided as a thread giving up its time slice gets a priority boost when resignaled, and that can lead to high context switches. In a multithreaded / server application, this can lead to a thrashing effect as the threads are battling for CPU time. Instead, rely on asynchronous functions and synchronization objects such as critical sections or mutexes / semaphores.

Extramundane answered 3/4, 2012 at 5:17 Comment(0)
B
4

As Bob Nadler mentioned Thread.Sleep(1) does not guarantee a sleep time of 1ms.

Here is an example using the Win32 multimedia timer to force a sleep of 1ms.

    [DllImport("winmm.dll")]
    internal static extern uint timeBeginPeriod(uint period);
    [DllImport("winmm.dll")]
    internal static extern uint timeEndPeriod(uint period);

    timeBeginPeriod(1);
    while(true)
    {
        Thread.Sleep(1); // will sleep 1ms every time
    }
    timeEndPeriod(1);

Testing this in a C# GUI application, I found that the application used about 50% of my CPU.

For more discussion on this topic see the following forum thread:

http://www.dotnet247.com/247reference/msgs/57/289291.aspx

Brattishing answered 6/2, 2009 at 23:39 Comment(0)
M
4

This is an old thread that comes up in a lot of my searches, but Win7 has a new scheduler and seems to behave differently than the above.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtEnd = DateTime.Now.AddSeconds(1.0);
            int i = 0;
            while (DateTime.Now < dtEnd)
            {
                i++;
                Thread.Sleep(1);
            }

            Console.WriteLine(i.ToString());

            i = 0;
            long lStart = DateTime.Now.Ticks;
            while (i++ < 1000)
                Thread.Sleep(1);

            long lTmp = (DateTime.Now.Ticks - lStart) / 10000;

            Console.WriteLine(lTmp.ToString());

            Console.Read();
        }
    }
}

With the above code, My first result gave 946. So in the timespan of 1 second using 1ms sleeps, I got 946 wake ups. That's very close to 1ms.

The second part asks how long it takes to do 1000 sleep events at 1ms each. I got 1034ms. Again, nearly 1ms.

This was on a 1.8ghz core2duo + Win7 using .Net 4.0

Edit: remember, sleep(x) doesn't mean wake up up at this time, it means wake me up no earlier than this time. It is not guaranteed. Although, you can increase the priority of the thread and Windows should schedule your thread before lower priority threads.

Mulderig answered 2/11, 2010 at 17:57 Comment(1)
A comment to add about the the Win 7 scheduler. I ran Bengie's example "namespace ConsoleApplication2" post and it reported 65 and 15600 indicating about ~15ms steps. This is a dual 3.33Mhx running .NET 3.5, Win 7. The odd thing is that yesterday I have logs with some code that was exhibiting sleep(1) much nearer to 1ms like his post claims. My conclusion is there is some setting or configuration that has changed on my machine but I am unable to determine. Same answer in debug or release modes with or without debugger. I did not use the begin/end TimePeriod. There is very little load on the maAraby
P
2

No, it won't hog all available CPU, because a sleeping thread will be switched out by the OS' scheduler when another thread has work to do.

Pounds answered 3/2, 2009 at 18:1 Comment(0)
A
2

No, it will not. You'll barely see it. Somewhere less than 1000 times a second this thread will wake up and do next to nothing before sleeping again.

Edit:

I had to check. Running on Java 1.5 , this test

@Test
public void testSpeed() throws InterruptedException {
    long currentTime = System.currentTimeMillis();
    int i = 0;
        while (i < 1000)
        {
            Thread.sleep(1);
            i++;
        }
    System.out.println("Executed in " + (System.currentTimeMillis() - currentTime));
}

Ran at approximately 500 sleeps per second on my 3ghz machine. I suppose C# should be fairly much the same. I assume someone will report back with C# numbers for this intensely important real-world benchmark. There was no observable CPU usage, by the way.

Alisa answered 3/2, 2009 at 18:1 Comment(2)
I doubt it would happen even that often: the argument to sleep is a minimum time, and context switching takes too long to get the many in anyway.Tootle
On modern multicore systems 1ms is a mighty long time. I wonder how this loop would actually run ?Alisa
T
0

A thread can at most hog one (logical) CPU at a time. And a 1ms sleep will not be hogging. Don't sweat it.

Tyrocidine answered 4/2, 2009 at 0:36 Comment(0)
P
0

also have a look at this: msdn forum

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace Test
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            for (int i = 0; i < 10; ++i)
            {
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();

                Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds);

                TimeBeginPeriod(1);
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();
                TimeEndPeriod(1);

                Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n");
            }
        }

        [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);
    }
}
Periodate answered 21/3, 2011 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.