简体   繁体   中英

How does Task.CompletedTask work with thread pool?

I'm new to C# asynchronous programming, just a question on the relationship between task and thread pool.

My understanding is: When we create a Task , this Task is queued in the thread pool and the thread pool will schedule a worker thread to run this Task

And I saw the code below:

public Task InputOutputC() {
   return Task.CompletedTask;
}

I don't quite get it, it seems that return a Task has already completed, which means a worker thread has already run this Task , but the meaning of Task is to let a worker thread in the thread pool to run it, if it has already finished, what's the point to return it to thread pool again and get executed again?

the meaning of Task is to let a worker thread in the thread pool to run it,

Running code on the thread pool is one way in which Task s manifest themselves.

Other ways to create Task s are to write async methods and to use Task.CompletedTask 1 or Task.FromResult<TResult> 2 .

Just because Task.Run causes code to run on the thread pool does not mean that these other uses of Task must also necessarily involve the thread pool.

For Task.CompletedTask , especially, this is "I've already done the work required, but I want to present it to other code as a Task . No additional code runs anywhere .

We can see in the reference source that this property just returns the task:

    /// <summary>A task that's already been completed successfully.</summary>
    private static Task s_completedTask;

    /// <summary>Gets a task that's already been completed successfully.</summary>
    /// <remarks>May not always return the same instance.</remarks>        
    public static Task CompletedTask
    {
        get
        {
            var completedTask = s_completedTask;
            if (completedTask == null)
                s_completedTask = completedTask = new Task(false, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken)); // benign initialization ----
            return completedTask;
        }
    }

1 As shown in the reference source later though, we often aren't even creating a new Task here, just reusing an existing one. But the team have obviously decided to forgo thread-safe initialisation of the property in favour of documenting that they won't guarantee to always return the same Task .

2 These latter two are quite similar, in that they represent "I've already done the work required, now for some reason I need to pass some other code a Task " 3 .

3 Often, and I'm guessing as is the case here, when you're implementing an interface or overriding a base class method that is Task returning but your code is fast and synchronous so you have no need to be async .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM