protected internal override void QueueTask(Task task) { TaskCreationOptions options = task.Options; if (Thread.IsThreadStartSupported && (options & TaskCreationOptions.LongRunning) != 0) { new Thread(s_longRunningThreadWork) { IsBackground = true, Name = ".NET Long Running Task" }.UnsafeStart(task); } else { ThreadPool.UnsafeQueueUserWorkItemInternal(task, (options & TaskCreationOptions.PreferFairness) == 0); } }
private static async Task Test() { Console.WriteLine(2); var v1 = await b(); var v = await a(); Console.WriteLine(6); } private static async Task<string> b() { Thread.Sleep(2000); return "3"; } private static async Task<string> a() { Console.WriteLine(3); await Task.Run(() => { Thread.Sleep(10000); Console.WriteLine(4); }); Console.WriteLine(5); return "3"; } static void Main(string[] args) { Console.WriteLine(1); var v = Test(); Console.WriteLine(7); Console.Read(); }
有啓動線程的il代碼(a_class) IL_0054: dup IL_0055: stsfld class [System.Runtime]System.Action ConsoleApp5.Program/'<>c'::'<>9__4_0' IL_005a: call class [System.Runtime]System.Threading.Tasks.Task [System.Runtime]System.Threading.Tasks.Task::Run(class [System.Runtime]System.Action) IL_005f: callvirt instance valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter [System.Runtime]System.Threading.Tasks.Task::GetAwaiter() IL_0064: stloc.3 IL_0065: ldloca.s V_3 IL_0067: call instance bool [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted() IL_006c: brtrue.s IL_00af // 如果爲true也就是任務跑完了,直接跳轉指令到獲取返回值,那部分代碼我沒貼了 IL_006e: ldarg.0 IL_006f: ldc.i4.0 IL_0070: dup IL_0071: stloc.0 IL_0072: stfld int32 ConsoleApp5.Program/'<a>d__4'::'<>1__state' IL_0077: ldarg.0 IL_0078: ldloc.3 IL_0079: stfld valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter ConsoleApp5.Program/'<a>d__4'::'<>u__1' IL_007e: ldarg.0 IL_007f: stloc.s V_4 IL_0081: ldarg.0 IL_0082: ldflda valuetype [System.Runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> ConsoleApp5.Program/'<a>d__4'::'<>t__builder' IL_0087: ldloca.s V_3 IL_0089: ldloca.s V_4 IL_008b: call instance void valuetype [System.Runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter,class ConsoleApp5.Program/'<a>d__4'>(!!0&, // 開始跑任務狀態 未啓動線程的il代碼(b_class) IL_0025: call instance string [System.Runtime]System.Int32::ToString() IL_002a: call string [System.Runtime]System.String::Concat(string, string) IL_002f: call void [System.Console]System.Console::WriteLine(string) IL_0034: nop IL_0035: ldstr "3" IL_003a: stloc.1 IL_003b: leave.s IL_0055 // 執行方法體裏面的代碼,直接執行leave指令,跳轉到指定地址 test方法的調用棧 IL_00aa: stfld string ConsoleApp5.Program/'<Test>d__0'::'<>s__6' IL_00af: call class [System.Runtime]System.Threading.Tasks.Task`1<string> ConsoleApp5.Program::b() // 創建b對象 IL_00b4: callvirt instance valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [System.Runtime]System.Threading.Tasks.Task`1<string>::GetAwaiter() IL_00b9: stloc.3 IL_00ba: ldloca.s V_3 IL_00bc: call instance bool valuetype [System.Runtime]System.Runtime.CompilerServices.TaskAwaiter`1<string>::get_IsCompleted() // 判斷任務是否完成,這裏是true IL_00c1: brtrue.s IL_0106 // 直接跳轉獲取result
public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredTaskAwaitable(this, continueOnCapturedContext); }
public readonly struct ConfiguredTaskAwaitable { private readonly ConfiguredTaskAwaitable.ConfiguredTaskAwaiter m_configuredTaskAwaiter; public ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter GetAwaiter() { return m_configuredTaskAwaiter; } ... }
public readonly struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion, IConfiguredTaskAwaiter { internal readonly Task m_task; internal ConfiguredTaskAwaiter(Task task, bool continueOnCapturedContext) { Debug.Assert(task != null, "Constructing an awaiter requires a task to await."); m_task = task; m_continueOnCapturedContext = continueOnCapturedContext; } public bool IsCompleted => m_task.IsCompleted; public void OnCompleted(Action continuation) { TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: true); } public void UnsafeOnCompleted(Action continuation) { TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: false); } public void GetResult() { TaskAwaiter.ValidateEnd(m_task); } }
internal static void AwaitUnsafeOnCompleted<TAwaiter>( ref TAwaiter awaiter, IAsyncStateMachineBox box) where TAwaiter : ICriticalNotifyCompletion { if ((null != (object?)default(TAwaiter)) && (awaiter is ITaskAwaiter)) { ref TaskAwaiter ta = ref Unsafe.As<TAwaiter, TaskAwaiter>(ref awaiter); // relies on TaskAwaiter/TaskAwaiter<T> having the same layout TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, continueOnCapturedContext: true); } else if ((null != (object?)default(TAwaiter)) && (awaiter is IConfiguredTaskAwaiter)) { ref ConfiguredTaskAwaitable.ConfiguredTaskAwaiter ta = ref Unsafe.As<TAwaiter, ConfiguredTaskAwaitable.ConfiguredTaskAwaiter>(ref awaiter); TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, ta.m_continueOnCapturedContext); } ... }
if (continueOnCapturedContext) // 這個就是最開始傳入的false,默認爲true { SynchronizationContext? syncCtx = SynchronizationContext.Current; // 獲取SynchronizationContext同步上下文,aspnetcore已經取消了這個對象 if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) { var tc = new SynchronizationContextAwaitTaskContinuation(syncCtx, stateMachineBox.MoveNextAction, flowExecutionContext: false); if (!AddTaskContinuation(tc, addBeforeOthers: false)) { tc.Run(this, canInlineContinuationTask: false); // 最終通過c.m_syncContext.Post(s_postCallback, c.m_action); Post callback } return; } else { TaskScheduler? scheduler = TaskScheduler.InternalCurrent; if (scheduler != null && scheduler != TaskScheduler.Default) { var tc = new TaskSchedulerAwaitTaskContinuation(scheduler, stateMachineBox.MoveNextAction, flowExecutionContext: false); if (!AddTaskContinuation(tc, addBeforeOthers: false)) { tc.Run(this, canInlineContinuationTask: false); } return; } } } if (!AddTaskContinuation(stateMachineBox, addBeforeOthers: false)) // 我們顯示指定false,所以會走這個邏輯。 { ThreadPool.UnsafeQueueUserWorkItemInternal(stateMachineBox, preferLocal: true); }