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.