[Day 8] .Net Task 底层(1)

前言

昨天聊过 Task.WhenAll , 得知其底层就是等待多个 Task 完成的机制, 那 Task 到底是甚麽呢 ?

Task类别代表不会传回值,而且通常会以非同步方式执行的单一作业。 Task 物件是工作架构 非同步模式 的其中一个核心元件,第一次是在 .NET Framework 4 中引进。 由於物件所执行的工作 Task 通常会线上程集区执行绪上以非同步方式执行,而不是在主应用程序执行绪上同步执行,因此您可以使用 Status 属性以及 IsCanceled 、 IsCompleted 和 IsFaulted 属性来判断工作的状态。 最常见的情况是使用 lambda 运算式来指定工作要执行的工作。

以上是微软文件里的说法, 这段叙述其实并不能说服我, 所以我打算从另一个角度是着揭开它的神秘面纱。 接下来对 Task 的探索可能会更为凌乱, 但我想探索底层就如同瞎子摸象, 每一次都摸一点点, 换个角度再摸一点点, 当累积足够, 就可以真正了解大象的模样。

从继承的父辈开始

public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable

可以看见继承自三种物件, 其中 IAsyncResult 放了一些变数, 比较简单之後遇到顺口提即可。

IDisposable 是释放资源相关, 跟同步非同步没太大关连。

我们把焦点放在 IThreadPoolWorkItem , Task 其实简单点说, 就是 IThreadPoolWorkItem 的封装。

进入 IThreadPoolWorkItem 可以看到, 他就是一个介面, 让人可以把 something 送入 TP ( threadPool )


// Interface to something that can be queued to the TP.  This is implemented by
// QueueUserWorkItemCallback, Task, and potentially other internal types.
// For example, SemaphoreSlim represents callbacks using its own type that
// implements IThreadPoolWorkItem.
//
// If we decide to expose some of the workstealing
// stuff, this is NOT the thing we want to expose to the public.
//
internal interface IThreadPoolWorkItem
{
    [SecurityCritical]
    void ExecuteWorkItem();
    [SecurityCritical]
    void MarkAborted(ThreadAbortException tae);
}

向下一层查看里面两个方法

[SecurityCritical]
public void ExecuteWorkItem()
{
	m_action.Invoke(m_completingTask);
}
[SecurityCritical]
public void MarkAborted(ThreadAbortException tae)
{
	/* NOP */
}

发现 MarkAborted 为空, 跳过, 以 ExecuteWorkItem 为主

其中两个变数 m_actionm_completingTask都是在 FinishContinuations() 中设定的, 这里偷偷超进度说一下, 该函数会在 Task 的某阶段变化时调用, 所以整个流程就是

  1. Task 的特定阶段改变
  2. 触发 FinishContinuations 会把待完成任务设置进 threadPool
  3. 此时当 Task 调用介面 IThreadPoolWorkItem 中的 ExecuteWorkItem 就会执行该任务

值得一说的是, 这并不是唯一一条 Task 设置非同步任务进 TP ,与触发 TP 中任务的路线。

而且在此刻我们没有真的看到 TP 的资料结构, 按照第二天的文章, 其想必也会是个 lock-free data structure 吧。

明天进度

透过阅读 FinishContinuations 来了解以下两个问题

  1. Task 设置任务进 TP 的路线。
  2. TP ( thread pool ) 的真实面貌

明天见!


<<:  Leetcode 挑战 Day 05 [136. Single Number]

>>:  Kotlin Android 第3天,从 0 到 ML - 基本语法和基本型态

Day 27 - ios 开发实作(今天还要继续吃吗APP-1、Swift UI Passing data 不同页面传值)

首先我们介绍一下这个APP的功能。 介绍 这个APP主要会有的功能如下: 计算今天吃的东西类型 计算...

[Day26] 第二十六章-使用patch送出分数并且修改前端edit.blade.php

前言 昨天我们做了新增point表的判断 今天要正式在point表确认送出分数 并储存於资料库里了 ...

D01 - 万事起头难

万事起头难,不开始就不难 ᕕ( ゚ ∀。)ᕗ 第一篇文章有请柴柴镇楼 (´∀`),开始挖坑! 首先让...

Day 05: 物件及资料结构、边界

「物件将它们的资料隐藏在抽象层後方,然後将操纵这些资料的函式暴露在外。资料结构则将资料暴露在外,且...

资安学习路上-网站常见漏洞与 Injection的爱恨情仇1

讲师 : 社长 林子婷(飞飞) 时间 : 19:00-21:00(授课时间共2小时) 授课内容:网...