QueueUserWorkItem weird behavior

47 Views Asked by At

I'm using ThreadPool.QueueUserWorkItem() to start some background tasks.

The ThreadPool concurrency behavior is weird. My CPU has 4 logical cores. I expect that there are only 4 running threads. However, the sample code shows different behavior.

  • in time 1/2/3, Why does mores threads are triggered?

here is sample code:

class Program
{
    static DateTime s_startTime = new DateTime();
    public static void Main()
    {
        // Queue the task.
        s_startTime = DateTime.Now;
        for (int i = 0; i < 1000; i++)
        {
            ThreadPool.QueueUserWorkItem(ThreadProc, i);
        }
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(100 * 1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object i)
    {
        DateTime thread_starttime = DateTime.Now;
        int a = Convert.ToInt32(i);
        double ss = (thread_starttime - s_startTime).TotalSeconds;
        Console.WriteLine("time:" + ss + ", start " + a);
        Thread.Sleep(10 * 1000);
        DateTime e = DateTime.Now;
        double ee = (e - s_startTime).TotalSeconds;
        Console.WriteLine("time:" + ee + ", end " + a);
    }
}

output

Main thread does some work, then sleeps.
time:0.0040027, start 0
time:0.0360007, start 3
time:0.0360007, start 1
time:0.0360007, start 2
time:1.0178537, start 4
time:2.0191713, start 5
time:3.019311, start 6
time:4.0194503, start 7
time:5.0195775, start 8
time:6.0195875, start 9
time:7.0219127, start 10
time:8.0214611, start 11
time:9.0181507, start 12
time:10.020686, end 0
time:10.020686, start 13
time:10.020686, start 14
time:10.038517, end 1
time:10.038517, start 15
time:10.038517, end 3
time:10.0403473, start 16
time:10.038517, end 2
time:10.0413736, start 17
time:11.0233302, end 4
time:11.0243333, start 18
time:11.0243333, start 19
1

There are 1 best solutions below

2
On

More threads will be triggered because you aren’t keeping your cores busy.

Thread.Sleep allows the thread to yield. Since your workers are mostly sleeping and not CPU bound the scheduler is free to schedule more threads.