个人感觉Task 的GetAwaiter和ConfigureAwait也是比较好理解的,首先看看他们的实现
public class Task<TResult> : Task { //Gets an awaiter used to await this public new TaskAwaiter<TResult> GetAwaiter() { return new TaskAwaiter<TResult>(this); } //Configures an awaiter used to await this public new ConfiguredTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext) { return new ConfiguredTaskAwaitable<TResult>(this, continueOnCapturedContext); } }
现在我们来看看TaskAwaiter<TResult>和ConfiguredTaskAwaitable<TResult>的实现:
public struct TaskAwaiter<TResult> : ICriticalNotifyCompletion { private readonly Task<TResult> m_task; internal TaskAwaiter(Task<TResult> task) { Contract.Requires(task != null, "Constructing an awaiter requires a task to await."); m_task = task; } public bool IsCompleted { get { return m_task.IsCompleted; } } public void OnCompleted(Action continuation) { TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true); } public void UnsafeOnCompleted(Action continuation) { TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false); } public TResult GetResult() { TaskAwaiter.ValidateEnd(m_task); return m_task.ResultOnSuccess; } } public struct ConfiguredTaskAwaitable<TResult> { private readonly ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter m_configuredTaskAwaiter; internal ConfiguredTaskAwaitable(Task<TResult> task, bool continueOnCapturedContext) { m_configuredTaskAwaiter = new ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter(task, continueOnCapturedContext); } public ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter GetAwaiter() { return m_configuredTaskAwaiter; } [HostProtection(Synchronization = true, ExternalThreading = true)] public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion { private readonly Task<TResult> m_task; private readonly bool m_continueOnCapturedContext; internal ConfiguredTaskAwaiter(Task<TResult> task, bool continueOnCapturedContext) { Contract.Requires(task != null, "Constructing an awaiter requires a task to await."); m_task = task; m_continueOnCapturedContext = continueOnCapturedContext; } public bool IsCompleted { get { return 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_continueOnC