为什么Task内部需要使用ManualResetEventSlim?

问题描述 投票:0回答:1

根据

Task
https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs的源代码,第1483章 so

Task

在内部使用

ManualResetEventSlim
内核同步结构
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;
    }
}

但是运行任务不是意味着线程池将“工作项”(在高级中表示为任务)放置到全局/本地队列中,然后由工作线程拾取来运行吗?是否需要使用任何内核线程同步构造?我的意思是它与谁同步?这里使用内核构造的目的是什么?

c# .net task-parallel-library
1个回答
0
投票
是否需要使用任何内核线程同步结构?

是的,对于

Wait

 方法。当您调用 
Wait 时,您希望阻塞当前线程,直到
Task
在另一个线程上完成。
ManualResetEventSlim
 执行阻塞当前线程的作用,直到来自完成线程的信号,以便当前线程可以解除阻塞。

运行
Task

不是意味着线程池将“工作项”(在高级中表示为任务)放入全局/本地队列中,然后由工作线程拾取来运行吗?


“基于委托的任务”就是这种情况,该任务在 2010 年首次随 .NET Framework 4.0 引入。下一个 .NET 版本(2012 年的 .NET Framework 4.5)引入了 Promise 风格的任务,它可以代表任何事情都不能只完成一个委托。今天的大多数任务都属于第二类。例如,

File.ReadAllTextAsync 返回承诺样式 Task

。在该方法运行的大部分时间内,
没有线程
Task
相关联。

© www.soinside.com 2019 - 2024. All rights reserved.