Are a .NET Task thread's resources returned back to the pool temporarily if the thread is waiting on an async operation to finish?

前端 未结 3 1374
再見小時候
再見小時候 2021-01-11 12:32

I have a TPL Task that does two things. First, it calls a web service. Second, it inserts some data into a database. I have up to 20 Tasks started at one time doing this sam

3条回答
  •  攒了一身酷
    2021-01-11 13:01

    If all an application's tasks block, each task will use a thread from the thread pool.

    If all tasks regularly await, the thread pool does not need to use a thread for every task.

    When your code awaits an operation that hasn't completed yet, the method's state is saved such that it can be resumed on any other thread.

    Idle threadpool threads get released after a while, so the actual thread which hits an await can be released from the thread pool while the method calling await is still running.

    Putting all this together, an async version of a routine can do the same work with less threads (assuming the workload has enough balance of time awaiting vs spinning the CPU).

    This code runs 100 tasks doing a synchronous wait:

    var numTasks = 100;
    for (int i = 0; i < numTasks; i++)
    {
        Thread.Sleep(5);
        Task.Run(() =>
        {
            Thread.Sleep(5000);
            Interlocked.Decrement(ref numTasks);
        });
    }
    while (numTasks > 0) Thread.Sleep(100);
    

    For the async wait, change it to:

        Task.Run(async () =>
        {
            await Task.Delay(5000);
            Interlocked.Decrement(ref numTasks);
        });
    

    On my system the async version grows the peak thread count half as much, and takes 20% of the time to do the same 'work'.

提交回复
热议问题