我们昨天聊到要透过解析 threadPool 档案中的 FinishContinuations
method 来了解 .Net 框架中 threadPool 的样貌以及使用。而FinishContinuations
会在特定阶段被 Task 调用。
资料来源 : https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,dadbf616e42976ee
internal void FinishContinuations()
{
// 设定目前执行任务完成, 因为此函数会在 Task 完成其任务时被调用
object continuationObject = Interlocked.Exchange(ref m_continuationObject, s_taskCompletionSentinel);
TplEtwProvider.Log.RunningContinuation(Id, continuationObject);
// 在 WhenAll 提过, 当别的物件要把某个任务放到某个任务後面执行时, 就会将那个任务加入到 连续任务区
// 当连续任务区为空, 此任务结束。
if (continuationObject != null)
{
// 连续任务区不为空要执行以下这段
if (AsyncCausalityTracer.LoggingOn)
AsyncCausalityTracer.TraceSynchronousWorkStart(CausalityTraceLevel.Required, this.Id, CausalitySynchronousWork.CompletionNotification);
// Skip synchronous execution of continuations if this task's thread was aborted
bool bCanInlineContinuations = !(((m_stateFlags & TASK_STATE_THREAD_WAS_ABORTED) != 0) ||
(Thread.CurrentThread.ThreadState == ThreadState.AbortRequested) ||
((m_stateFlags & (int)TaskCreationOptions.RunContinuationsAsynchronously) != 0));
// 若是连续任务区只有一个 Action 就直接执行或送入排程(这个 method 有点东西, 目前不能细说)
Action singleAction = continuationObject as Action;
if (singleAction != null)
{
AwaitTaskContinuation.RunOrScheduleAction(singleAction, bCanInlineContinuations, ref t_currentTask);
LogFinishCompletionNotification();
return;
}
// Handle the single-ITaskCompletionAction case
ITaskCompletionAction singleTaskCompletionAction = continuationObject as ITaskCompletionAction;
if (singleTaskCompletionAction != null)
{
// 可以接着执行
if (bCanInlineContinuations)
{
// 直接用同一个 Task 接着执行这个任务
singleTaskCompletionAction.Invoke(this);
}
else
{
// 不能用同一个 task 接着执行, 把 Task 打包加入 TP
ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(singleTaskCompletionAction, this), forceGlobal: false);
}
LogFinishCompletionNotification();
return;
}
// 此段流程和上一段很像, 略。
TaskContinuation singleTaskContinuation = continuationObject as TaskContinuation;
if (singleTaskContinuation != null)
{
singleTaskContinuation.Run(this, bCanInlineContinuations);
LogFinishCompletionNotification();
return;
}
// Not a single; attempt to cast as list
List<object> continuations = continuationObject as List<object>;
// 连续任务为空
if (continuations == null)
{
LogFinishCompletionNotification();
return; // Not a single or a list; just return
}
//
// Begin processing of continuation list
//
// 此段是在处理, 连续任务区 有多个任务时的状况, 略, 明天聊
}
}
可以发现以下流程
此外, 连续任务若有多个任务, 有另一套处理程序。
可以在同一个 Thread 接着执行的评断标准之後也会聊到。
虽然只有一个连续任务看起来有三种处理的 CASE , 但究其本质都是差不多的。
明天我们针对 ITaskCompletionAction
这个 CASE 往下,
要看
singleTaskCompletionAction.Invoke(this);
和
ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(singleTaskCompletionAction, this), forceGlobal: false);
为何一个可以使原来的 Task 接着执行连续任务, 另一个可以 把 task 送入 TP 给别人执行。
今天因为篇幅问题, 没有聊到 TP , 所以明天就继续写, 看能不能把上面那两个 method 聊完。
明天见!
前言 各位早安,书接上回我们学会换页爬取文章标题了,今天我们要对程序码进行一些改良,使其更符合我们的...
Aloha!我是少女人妻 Uerica!这篇是最後一篇了,虽然没有写到很深,但对搜寻引擎真的有多了...
年中才刚攻破 JavaScript 30 挑战一天一题 JavaScript,过不久因缘际会接了一个...
假设我们取得受害主机的 shell (cmd.exe 或 powershell)可以根据自己的需求取...
CSS是什麽? CSS,全名为Cascading Style Sheets,中文为阶层式样式表。跟H...