0

In this code, when you use await Task.Delay(5000);, the line Console.WriteLine("START TestSemaPhoreSlims:ID[" + ids + "]... is executed without any delay.

However, when you use Thread.Sleep(5000);, you observe a delay in the logs starting from "START TestSemaPhoreSlims:ID[ID:7] workerThreads>>>2040: times>>>16-06-44". The expected behavior is that the Console.WriteLine statement should execute immediately without any delay.

I hope this clarifies the issue. Let me know if you have any further questions.

public class SemaPhoreTest1s
{
    public SemaPhoreTest1s()
    {
        for (int i = 1; i <= 10; i++)
        {
            int idnums = i;

            Task.Run(() => TestSemaPhoreSlims("ID:" + idnums));
        }

        Console.WriteLine("MAIN THREAD:" + Thread.CurrentThread.ManagedThreadId);

        Console.ReadLine();
    }

    public async void TestSemaPhoreSlims(string ids)
    {
        int workerThreads, completionPortThreads;
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);

        Console.WriteLine("START TestSemaPhoreSlims:ID[" + ids + "] workerThreads>>>" + workerThreads + ": times>>>" + DateTime.Now.ToString("HH-mm-ss"));

        Thread.Sleep(5000);
        //await Task.Delay(5000);
    }
}
MAIN THREAD:1  
START TestSemaPhoreSlims:ID\[ID:2\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:1\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:5\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:4\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:3\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:6\] workerThreads\>\>\>2041: times\>\>\>16-06-43  
START TestSemaPhoreSlims:ID\[ID:7\] workerThreads\>\>\>2040: times\>\>\>16-06-44  
START TestSemaPhoreSlims:ID\[ID:8\] workerThreads\>\>\>2039: times\>\>\>16-06-45  
START TestSemaPhoreSlims:ID\[ID:9\] workerThreads\>\>\>2038: times\>\>\>16-06-46  
START TestSemaPhoreSlims:ID\[ID:10\] workerThreads\>\>\>2037: times\>\>\>16-06-47
rene
  • 41,474
  • 78
  • 114
  • 152
  • await runs an asynchronous process and then waits for a signal indicating the process terminated. You are running TASK which also runs an asynchronous process and doesn't wait for the Delay to finish. So TASK immediately signals await to continue so you do not get any delay. – jdweng May 28 '23 at 07:42
  • 2
    [*"the thread pool doesn't immediately create new threads in all situations. In order to cope with bursts of small tasks, it limits how quickly it creates new threads. IIRC, it will create one thread every 0.5 seconds if there are outstanding tasks, up to the maximum number of threads."*](https://stackoverflow.com/a/6000891/11683). However note that [tasks are not threads](https://stackoverflow.com/questions/17661428/async-stay-on-the-current-thread). – GSerg May 28 '23 at 08:19
  • What I'm curious about Using Thread.Sleep(5000); this part "START TestSemaPhoreSlims:ID[ID:7] workerThreads>>>2040: times>>>17-27-40" There is a delay from the beginning, and the console is taken. Of course await Task.Delay(5000); or if you get rid of Thread.Sleep(5000) No delay occurs. How does Thread.Sleep(5000) affect the ThreadPool's ThreadWorker? – licenniezh May 28 '23 at 08:29
  • 2
    OP is basically asking, why there is sudden delay on WorkerThread 8,9,10 and why they don't start all together. I feel like some of you are trying to comment on different aspect of the code which is irrelevant / is there to showcase and test. – Tatranskymedved May 28 '23 at 09:13
  • @Tatranskymedved Thank you for pointing in the right direction :o) – Sir Rufo May 28 '23 at 10:17

1 Answers1

2

The ThreadPool starts with an amount of worker threads defined. You can get that information by calling ThreadPool.GetMinThreads method, which returns the minimum for worker- and completionPort threads.

The thread pool increases the number of worker threads while running but it takes some time to do so. You can watch this, when you repeat the code again and again within the same process. Also the thread pool will kill worker threads after an amount of time when they are not used.

To get all tasks running from the start set the minimum worker threads to the value you are satisfied with (here 10 will be enough).

// set before you run your code
ThreadPool.SetMinThreads( 10, 1 );

Now every task should run as you expected.

When you want to watch how the number of worker threads changes you can print out the Threadpool.ThreadCount value.


Why does this not happen with Task.Delay?

Because with Task.Delay there is no Thread (for that delay). Behind the scenes there is a state machine that will be activated again from the Scheduler when the delay is over.

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73