According to the source code of Task https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs,1483
So Task uses ManualResetEventSlim kernel synchronization construct internally
internal ManualResetEventSlim CompletedEvent
{
get
{
ContingentProperties contingentProps = EnsureContingentPropertiesInitialized();
if (contingentProps.m_completionEvent == null)
{
bool wasCompleted = IsCompleted;
ManualResetEventSlim newMre = new ManualResetEventSlim(wasCompleted); // <----------------
if (Interlocked.CompareExchange(ref contingentProps.m_completionEvent, newMre, null) != null)
{
// Someone else already set the value, so we will just close the event right away.
newMre.Dispose();
}
else if (!wasCompleted && IsCompleted)
{
// We published the event as unset, but the task has subsequently completed.
// Set the event's state properly so that callers don't deadlock.
ContingentProperties.SetEvent(newMre);
}
}
return contingentProps.m_completionEvent;
}
}
But isn't that running a Task means threadpool places the "work item" (represented as Task in high level) to the global/local queue then it will picked up by a worker thread to run? is there a need to use any kernel thread synchronization construct? I mean it synchronize with whom? what's the purpose of using a kernel construct here?
Yes, for the
Waitmethod. When you callWait, you want to block the current thread until theTaskcompletes on another thread. TheManualResetEventSlimperforms the role of blocking the current thread, until a signal comes from the completing thread so that the current thread can be unblocked.This is the case with the delegate-based tasks, that were introduced with the .NET Framework 4.0 at 2010. The next .NET release (.NET Framework 4.5 at 2012) introduced the
async/awaittechnology, that made promise-style tasks more prominent. These tasks can represent anything and not just the completion of a delegate. Most tasks today fall in the second category. For example theFile.ReadAllTextAsyncreturns a promise-styleTask. There is no thread tied to theTaskfor the majority of the time that this operation is in-flight.