Skip to content

Instantly share code, notes, and snippets.

@wi7a1ian
Last active September 19, 2023 12:38
Show Gist options
  • Save wi7a1ian/42ad24624850e9fa8842434ad329a0e6 to your computer and use it in GitHub Desktop.
Save wi7a1ian/42ad24624850e9fa8842434ad329a0e6 to your computer and use it in GitHub Desktop.
Async/await internals in C# #csharp
class Program
{
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
CancellationTokenSource cts = new CancellationTokenSource();
var a = new SomeABClass();
var l = await a.AAA(cts.Token);
}
public class SomeABClass
{
public async Task<long> AAA(CancellationToken token)
{
Stopwatch tick = new Stopwatch();
tick.Start();
await BBB(token);
await CCC(token);
tick.Stop();
return tick.ElapsedMilliseconds;
}
private async Task BBB(CancellationToken token)
{
await Task.Delay(TimeSpan.FromSeconds(1), token);
}
private async Task CCC(CancellationToken token)
{
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
}
}
}
internal class Program
{
private static void Main(string[] args)
{
MainAsync().Wait();
}
[AsyncStateMachine(typeof(<MainAsync>d__1))]
[DebuggerStepThrough]
private static Task MainAsync()
{
<MainAsync>d__1 stateMachine = new <MainAsync>d__1();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public class SomeABClass
{
[AsyncStateMachine(typeof(<AAA>d__0))]
[DebuggerStepThrough]
public Task<long> AAA(CancellationToken token)
{
<AAA>d__0 stateMachine = new <AAA>d__0();
stateMachine.<>4__this = this;
stateMachine.token = token;
stateMachine.<>t__builder = AsyncTaskMethodBuilder<long>.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder<long> <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<BBB>d__1))]
[DebuggerStepThrough]
private Task BBB(CancellationToken token)
{
<BBB>d__1 stateMachine = new <BBB>d__1();
stateMachine.<>4__this = this;
stateMachine.token = token;
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<CCC>d__2))]
[DebuggerStepThrough]
private Task CCC(CancellationToken token)
{
<CCC>d__2 stateMachine = new <CCC>d__2();
stateMachine.<>4__this = this;
stateMachine.token = token;
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
}
}
[CompilerGenerated]
private sealed class <AAA>d__0 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder<long> <>t__builder;
public CancellationToken token;
public SomeABClass <>4__this;
private Stopwatch <tick>5__1;
private TaskAwaiter <>u__1;
private void MoveNext()
{
int num = <>1__state;
long elapsedMilliseconds;
try
{
TaskAwaiter awaiter;
TaskAwaiter awaiter2;
if (num != 0)
{
if (num == 1)
{
awaiter = <>u__1;
<>u__1 = default(TaskAwaiter);
num = (<>1__state = -1);
goto IL_00ff;
}
<tick>5__1 = new Stopwatch();
<tick>5__1.Start();
awaiter2 = <>4__this.BBB(token).GetAwaiter();
if (!awaiter2.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = awaiter2;
<AAA>d__0 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine);
return;
}
}
else
{
awaiter2 = <>u__1;
<>u__1 = default(TaskAwaiter);
num = (<>1__state = -1);
}
awaiter2.GetResult();
awaiter = <>4__this.CCC(token).GetAwaiter();
if (!awaiter.IsCompleted)
{
num = (<>1__state = 1);
<>u__1 = awaiter;
<AAA>d__0 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
return;
}
goto IL_00ff;
IL_00ff:
awaiter.GetResult();
<tick>5__1.Stop();
elapsedMilliseconds = <tick>5__1.ElapsedMilliseconds;
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult(elapsedMilliseconds);
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[CompilerGenerated]
private sealed class <BBB>d__1 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder <>t__builder;
public CancellationToken token;
public SomeABClass <>4__this;
private TaskAwaiter <>u__1;
private void MoveNext()
{
int num = <>1__state;
try
{
TaskAwaiter awaiter;
if (num != 0)
{
awaiter = Task.Delay(TimeSpan.FromSeconds(1.0), token).GetAwaiter();
if (!awaiter.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = awaiter;
<BBB>d__1 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
return;
}
}
else
{
awaiter = <>u__1;
<>u__1 = default(TaskAwaiter);
num = (<>1__state = -1);
}
awaiter.GetResult();
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult();
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[CompilerGenerated]
private sealed class <CCC>d__2 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder <>t__builder;
public CancellationToken token;
public SomeABClass <>4__this;
private ConfiguredTaskAwaitable.ConfiguredTaskAwaiter <>u__1;
private void MoveNext()
{
int num = <>1__state;
try
{
ConfiguredTaskAwaitable.ConfiguredTaskAwaiter awaiter;
if (num != 0)
{
awaiter = Task.Delay(TimeSpan.FromSeconds(1.0), token).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
if (!awaiter.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = awaiter;
<CCC>d__2 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
return;
}
}
else
{
awaiter = <>u__1;
<>u__1 = default(ConfiguredTaskAwaitable.ConfiguredTaskAwaiter);
num = (<>1__state = -1);
}
awaiter.GetResult();
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult();
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[CompilerGenerated]
private sealed class <MainAsync>d__1 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder <>t__builder;
private CancellationTokenSource <cts>5__1;
private SomeABClass <a>5__2;
private long <l>5__3;
private long <>s__4;
private TaskAwaiter<long> <>u__1;
private void MoveNext()
{
int num = <>1__state;
try
{
TaskAwaiter<long> awaiter;
if (num != 0)
{
<cts>5__1 = new CancellationTokenSource();
<a>5__2 = new SomeABClass();
awaiter = <a>5__2.AAA(<cts>5__1.Token).GetAwaiter();
if (!awaiter.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = awaiter;
<MainAsync>d__1 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
return;
}
}
else
{
awaiter = <>u__1;
<>u__1 = default(TaskAwaiter<long>);
num = (<>1__state = -1);
}
<>s__4 = awaiter.GetResult();
<l>5__3 = <>s__4;
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult();
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[__DynamicallyInvokable]
[HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public struct AsyncTaskMethodBuilder
{
private static readonly Task<VoidTaskResult> s_cachedCompleted = AsyncTaskMethodBuilder<VoidTaskResult>.s_defaultResultTask;
private AsyncTaskMethodBuilder<VoidTaskResult> m_builder;
[__DynamicallyInvokable]
public Task Task
{
[__DynamicallyInvokable]
get
{
return m_builder.Task;
}
}
private object ObjectIdForDebugger => Task;
[__DynamicallyInvokable]
public static AsyncTaskMethodBuilder Create()
{
return default(AsyncTaskMethodBuilder);
}
[SecuritySafeCritical]
[DebuggerStepThrough]
[__DynamicallyInvokable]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
if (stateMachine == null)
{
throw new ArgumentNullException("stateMachine");
}
ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);
RuntimeHelpers.PrepareConstrainedRegions();
try
{
ExecutionContext.EstablishCopyOnWriteScope(ref ecsw);
stateMachine.MoveNext();
}
finally
{
ecsw.Undo();
}
}
[__DynamicallyInvokable]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
m_builder.SetStateMachine(stateMachine);
}
[__DynamicallyInvokable]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
{
m_builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
}
[__DynamicallyInvokable]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
{
m_builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
}
[__DynamicallyInvokable]
public void SetResult()
{
m_builder.SetResult(s_cachedCompleted);
}
[__DynamicallyInvokable]
public void SetException(Exception exception)
{
m_builder.SetException(exception);
}
internal void SetNotificationForWaitCompletion(bool enabled)
{
m_builder.SetNotificationForWaitCompletion(enabled);
}
}
public struct AsyncTaskMethodBuilder<TResult>
{
private sealed class DebugFinalizableAsyncStateMachineBox<TStateMachine> : AsyncStateMachineBox<TStateMachine> where TStateMachine : notnull, IAsyncStateMachine
{
~DebugFinalizableAsyncStateMachineBox()
{
if (!base.IsCompleted)
{
TplEventSource.Log.IncompleteAsyncMethod(this);
}
}
}
private class AsyncStateMachineBox<TStateMachine> : Task<TResult>, IAsyncStateMachineBox where TStateMachine : notnull, IAsyncStateMachine
{
private static readonly ContextCallback s_callback = new ContextCallback(ExecutionContextCallback);
private Action _moveNextAction;
[AllowNull]
[MaybeNull]
public TStateMachine StateMachine;
public ExecutionContext Context;
public Action MoveNextAction => _moveNextAction ?? (_moveNextAction = new Action(MoveNext));
private static void ExecutionContextCallback(object s)
{
Unsafe.As<AsyncStateMachineBox<TStateMachine>>(s).StateMachine.MoveNext();
}
internal sealed override void ExecuteFromThreadPool(Thread threadPoolThread)
{
MoveNext(threadPoolThread);
}
public void MoveNext()
{
MoveNext(null);
}
private void MoveNext(Thread threadPoolThread)
{
bool loggingOn = AsyncCausalityTracer.LoggingOn;
if (loggingOn)
{
AsyncCausalityTracer.TraceSynchronousWorkStart(this, CausalitySynchronousWork.Execution);
}
ExecutionContext context = Context;
if (context == null)
{
StateMachine.MoveNext();
}
else if (threadPoolThread == null)
{
ExecutionContext.RunInternal(context, s_callback, this);
}
else
{
ExecutionContext.RunFromThreadPoolDispatchLoop(threadPoolThread, context, s_callback, this);
}
if (base.IsCompleted)
{
if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
{
System.Threading.Tasks.Task.RemoveFromActiveTasks(this);
}
StateMachine = default(TStateMachine);
Context = null;
if (AsyncMethodBuilderCore.TrackAsyncMethodCompletion)
{
GC.SuppressFinalize(this);
}
}
if (loggingOn)
{
AsyncCausalityTracer.TraceSynchronousWorkCompletion(CausalitySynchronousWork.Execution);
}
}
IAsyncStateMachine IAsyncStateMachineBox.GetStateMachineObject()
{
return StateMachine;
}
}
internal static readonly Task<TResult> s_defaultResultTask = AsyncTaskCache.CreateCacheableTask(default(TResult));
private Task<TResult> m_task;
public Task<TResult> Task
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return m_task ?? InitializeTaskAsPromise();
}
}
internal object ObjectIdForDebugger => m_task ?? InitializeTaskAsStateMachineBox();
public static AsyncTaskMethodBuilder<TResult> Create()
{
return default(AsyncTaskMethodBuilder<TResult>);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[DebuggerStepThrough]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
AsyncMethodBuilderCore.Start(ref stateMachine);
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
AsyncMethodBuilderCore.SetStateMachine(stateMachine, m_task);
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
{
try
{
awaiter.OnCompleted(GetStateMachineBox(ref stateMachine).MoveNextAction);
}
catch (Exception exception)
{
System.Threading.Tasks.Task.ThrowAsync(exception, null);
}
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
{
IAsyncStateMachineBox stateMachineBox = GetStateMachineBox(ref stateMachine);
if (default(TAwaiter) != null && awaiter is ITaskAwaiter)
{
TaskAwaiter.UnsafeOnCompletedInternal(Unsafe.As<TAwaiter, TaskAwaiter>(ref awaiter).m_task, stateMachineBox, continueOnCapturedContext: true);
}
else if (default(TAwaiter) != null && awaiter is IConfiguredTaskAwaiter)
{
ref ConfiguredTaskAwaitable.ConfiguredTaskAwaiter reference = ref Unsafe.As<TAwaiter, ConfiguredTaskAwaitable.ConfiguredTaskAwaiter>(ref awaiter);
TaskAwaiter.UnsafeOnCompletedInternal(reference.m_task, stateMachineBox, reference.m_continueOnCapturedContext);
}
else if (default(TAwaiter) != null && awaiter is IStateMachineBoxAwareAwaiter)
{
try
{
((IStateMachineBoxAwareAwaiter)(object)awaiter).AwaitUnsafeOnCompleted(stateMachineBox);
}
catch (Exception exception)
{
System.Threading.Tasks.Task.ThrowAsync(exception, null);
}
}
else
{
try
{
awaiter.UnsafeOnCompleted(stateMachineBox.MoveNextAction);
}
catch (Exception exception2)
{
System.Threading.Tasks.Task.ThrowAsync(exception2, null);
}
}
}
private IAsyncStateMachineBox GetStateMachineBox<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : notnull, IAsyncStateMachine
{
ExecutionContext executionContext = ExecutionContext.Capture();
AsyncStateMachineBox<TStateMachine> asyncStateMachineBox = m_task as AsyncStateMachineBox<TStateMachine>;
if (asyncStateMachineBox != null)
{
if (asyncStateMachineBox.Context != executionContext)
{
asyncStateMachineBox.Context = executionContext;
}
return asyncStateMachineBox;
}
AsyncStateMachineBox<IAsyncStateMachine> asyncStateMachineBox2 = m_task as AsyncStateMachineBox<IAsyncStateMachine>;
if (asyncStateMachineBox2 != null)
{
if (asyncStateMachineBox2.StateMachine == null)
{
Debugger.NotifyOfCrossThreadDependency();
asyncStateMachineBox2.StateMachine = stateMachine;
}
asyncStateMachineBox2.Context = executionContext;
return asyncStateMachineBox2;
}
Debugger.NotifyOfCrossThreadDependency();
AsyncStateMachineBox<TStateMachine> asyncStateMachineBox3 = (AsyncStateMachineBox<TStateMachine>)(m_task = (AsyncMethodBuilderCore.TrackAsyncMethodCompletion ? CreateDebugFinalizableAsyncStateMachineBox<TStateMachine>() : new AsyncStateMachineBox<TStateMachine>()));
asyncStateMachineBox3.StateMachine = stateMachine;
asyncStateMachineBox3.Context = executionContext;
if (AsyncCausalityTracer.LoggingOn)
{
AsyncCausalityTracer.TraceOperationCreation(asyncStateMachineBox3, "Async: " + stateMachine.GetType().Name);
}
if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
{
System.Threading.Tasks.Task.AddToActiveTasks(asyncStateMachineBox3);
}
return asyncStateMachineBox3;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static AsyncTaskMethodBuilder<TResult>.AsyncStateMachineBox<TStateMachine> CreateDebugFinalizableAsyncStateMachineBox<TStateMachine>() where TStateMachine : notnull, IAsyncStateMachine
{
return new DebugFinalizableAsyncStateMachineBox<TStateMachine>();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private Task<TResult> InitializeTaskAsPromise()
{
return m_task = new Task<TResult>();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private Task<TResult> InitializeTaskAsStateMachineBox()
{
return m_task = (AsyncMethodBuilderCore.TrackAsyncMethodCompletion ? CreateDebugFinalizableAsyncStateMachineBox<IAsyncStateMachine>() : new AsyncStateMachineBox<IAsyncStateMachine>());
}
public void SetResult(TResult result)
{
if (m_task == null)
{
m_task = GetTaskForResult(result);
}
else
{
SetExistingTaskResult(result);
}
}
private void SetExistingTaskResult([AllowNull] TResult result)
{
if (AsyncCausalityTracer.LoggingOn)
{
AsyncCausalityTracer.TraceOperationCompletion(m_task, AsyncCausalityStatus.Completed);
}
if (!m_task.TrySetResult(result))
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
}
internal void SetResult(Task<TResult> completedTask)
{
if (m_task == null)
{
m_task = completedTask;
}
else
{
SetExistingTaskResult(default(TResult));
}
}
public void SetException(Exception exception)
{
if (exception == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception);
}
Task<TResult> task = Task;
OperationCanceledException ex = exception as OperationCanceledException;
if (!((ex != null) ? task.TrySetCanceled(ex.CancellationToken, ex) : task.TrySetException(exception)))
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
}
internal void SetNotificationForWaitCompletion(bool enabled)
{
(m_task ?? InitializeTaskAsStateMachineBox()).SetNotificationForWaitCompletion(enabled);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Task<TResult> GetTaskForResult(TResult result)
{
if (default(TResult) != null)
{
if (typeof(TResult) == typeof(bool))
{
Task<bool> value = ((bool)(object)result) ? AsyncTaskCache.TrueTask : AsyncTaskCache.FalseTask;
return Unsafe.As<Task<TResult>>(value);
}
if (typeof(TResult) == typeof(int))
{
int num = (int)(object)result;
if (num < 9 && num >= -1)
{
Task<int> value2 = AsyncTaskCache.Int32Tasks[num - -1];
return Unsafe.As<Task<TResult>>(value2);
}
}
else if ((typeof(TResult) == typeof(uint) && (uint)(object)result == 0) || (typeof(TResult) == typeof(byte) && (byte)(object)result == 0) || (typeof(TResult) == typeof(sbyte) && (sbyte)(object)result == 0) || (typeof(TResult) == typeof(char) && (char)(object)result == '\0') || (typeof(TResult) == typeof(long) && (long)(object)result == 0L) || (typeof(TResult) == typeof(ulong) && (ulong)(object)result == 0L) || (typeof(TResult) == typeof(short) && (short)(object)result == 0) || (typeof(TResult) == typeof(ushort) && (ushort)(object)result == 0) || (typeof(TResult) == typeof(IntPtr) && (IntPtr)0 == (IntPtr)(object)result) || (typeof(TResult) == typeof(UIntPtr) && (UIntPtr)0u == (UIntPtr)(object)result))
{
return s_defaultResultTask;
}
}
else if (result == null)
{
return s_defaultResultTask;
}
return new Task<TResult>(result);
}
}
// System.Threading.Tasks.AwaitTaskContinuation
internal static void UnsafeScheduleAction(Action action, Task task)
{
AwaitTaskContinuation awaitTaskContinuation = new AwaitTaskContinuation(action, flowExecutionContext: false);
TplEventSource log = TplEventSource.Log;
if (log.IsEnabled() && task != null)
{
awaitTaskContinuation.m_continuationId = Task.NewId();
log.AwaitTaskContinuationScheduled((task.ExecutingTaskScheduler ?? TaskScheduler.Default).Id, task.Id, awaitTaskContinuation.m_continuationId);
}
ThreadPool.UnsafeQueueUserWorkItemInternal(awaitTaskContinuation, preferLocal: true);
}
public readonly struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion, IConfiguredTaskAwaiter
{
internal readonly Task m_task;
internal readonly bool m_continueOnCapturedContext;
public bool IsCompleted => m_task.IsCompleted;
internal ConfiguredTaskAwaiter(Task task, bool continueOnCapturedContext)
{
m_task = task;
m_continueOnCapturedContext = continueOnCapturedContext;
}
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);
}
[StackTraceHidden]
public void GetResult()
{
TaskAwaiter.ValidateEnd(m_task);
}
}
// System.Threading.Tasks.Task
private bool AddTaskContinuation(object tc, bool addBeforeOthers)
{
if (IsCompleted)
{
return false;
}
if (m_continuationObject != null || Interlocked.CompareExchange(ref m_continuationObject, tc, null) != null)
{
return AddTaskContinuationComplex(tc, addBeforeOthers);
}
return true;
}
internal void SetContinuationForAwait(Action continuationAction, bool continueOnCapturedContext, bool flowExecutionContext)
{
TaskContinuation taskContinuation = null;
if (continueOnCapturedContext)
{
SynchronizationContext current = SynchronizationContext.Current;
if (current != null && current.GetType() != typeof(SynchronizationContext))
{
taskContinuation = new SynchronizationContextAwaitTaskContinuation(current, continuationAction, flowExecutionContext);
}
else
{
TaskScheduler internalCurrent = TaskScheduler.InternalCurrent;
if (internalCurrent != null && internalCurrent != TaskScheduler.Default)
{
taskContinuation = new TaskSchedulerAwaitTaskContinuation(internalCurrent, continuationAction, flowExecutionContext);
}
}
}
if (taskContinuation == null && flowExecutionContext)
{
taskContinuation = new AwaitTaskContinuation(continuationAction, flowExecutionContext: true);
}
if (taskContinuation != null)
{
if (!AddTaskContinuation(taskContinuation, addBeforeOthers: false))
{
taskContinuation.Run(this, canInlineContinuationTask: false);
}
}
else if (!AddTaskContinuation(continuationAction, addBeforeOthers: false))
{
AwaitTaskContinuation.UnsafeScheduleAction(continuationAction, this);
}
}
internal void UnsafeSetContinuationForAwait(IAsyncStateMachineBox stateMachineBox, bool continueOnCapturedContext)
{
if (continueOnCapturedContext)
{
SynchronizationContext current = SynchronizationContext.Current;
if (current != null && current.GetType() != typeof(SynchronizationContext))
{
SynchronizationContextAwaitTaskContinuation synchronizationContextAwaitTaskContinuation = new SynchronizationContextAwaitTaskContinuation(current, stateMachineBox.MoveNextAction, flowExecutionContext: false);
if (!AddTaskContinuation(synchronizationContextAwaitTaskContinuation, addBeforeOthers: false))
{
synchronizationContextAwaitTaskContinuation.Run(this, canInlineContinuationTask: false);
}
return;
}
TaskScheduler internalCurrent = TaskScheduler.InternalCurrent;
if (internalCurrent != null && internalCurrent != TaskScheduler.Default)
{
TaskSchedulerAwaitTaskContinuation taskSchedulerAwaitTaskContinuation = new TaskSchedulerAwaitTaskContinuation(internalCurrent, stateMachineBox.MoveNextAction, flowExecutionContext: false);
if (!AddTaskContinuation(taskSchedulerAwaitTaskContinuation, addBeforeOthers: false))
{
taskSchedulerAwaitTaskContinuation.Run(this, canInlineContinuationTask: false);
}
return;
}
}
if (!AddTaskContinuation(stateMachineBox, addBeforeOthers: false))
{
ThreadPool.UnsafeQueueUserWorkItemInternal(stateMachineBox, preferLocal: true);
}
}
public readonly struct TaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion, ITaskAwaiter
{
internal readonly Task m_task;
public bool IsCompleted => m_task.IsCompleted;
internal TaskAwaiter(Task task)
{
m_task = task;
}
public void OnCompleted(Action continuation)
{
OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
}
public void UnsafeOnCompleted(Action continuation)
{
OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
}
[StackTraceHidden]
public void GetResult()
{
ValidateEnd(m_task);
}
[StackTraceHidden]
internal static void ValidateEnd(Task task)
{
if (task.IsWaitNotificationEnabledOrNotRanToCompletion)
{
HandleNonSuccessAndDebuggerNotification(task);
}
}
[StackTraceHidden]
private static void HandleNonSuccessAndDebuggerNotification(Task task)
{
if (!task.IsCompleted)
{
bool flag = task.InternalWait(-1, default(CancellationToken));
}
task.NotifyDebuggerOfWaitCompletionIfNecessary();
if (!task.IsCompletedSuccessfully)
{
ThrowForNonSuccess(task);
}
}
[StackTraceHidden]
private static void ThrowForNonSuccess(Task task)
{
switch (task.Status)
{
case TaskStatus.Canceled:
task.GetCancellationExceptionDispatchInfo()?.Throw();
throw new TaskCanceledException(task);
case TaskStatus.Faulted:
{
ReadOnlyCollection<ExceptionDispatchInfo> exceptionDispatchInfos = task.GetExceptionDispatchInfos();
if (exceptionDispatchInfos.Count > 0)
{
exceptionDispatchInfos[0].Throw();
break;
}
throw task.Exception;
}
}
}
internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
{
if (continuation == null)
{
throw new ArgumentNullException("continuation");
}
if (TplEventSource.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
{
continuation = OutputWaitEtwEvents(task, continuation);
}
task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext);
}
internal static void UnsafeOnCompletedInternal(Task task, IAsyncStateMachineBox stateMachineBox, bool continueOnCapturedContext)
{
if (TplEventSource.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
{
task.SetContinuationForAwait(OutputWaitEtwEvents(task, stateMachineBox.MoveNextAction), continueOnCapturedContext, flowExecutionContext: false);
}
else
{
task.UnsafeSetContinuationForAwait(stateMachineBox, continueOnCapturedContext);
}
}
private static Action OutputWaitEtwEvents(Task task, Action continuation)
{
if (Task.s_asyncDebuggingEnabled)
{
Task.AddToActiveTasks(task);
}
TplEventSource log = TplEventSource.Log;
if (log.IsEnabled())
{
Task internalCurrent = Task.InternalCurrent;
Task task2 = AsyncMethodBuilderCore.TryGetContinuationTask(continuation);
log.TaskWaitBegin(internalCurrent?.m_taskScheduler.Id ?? TaskScheduler.Default.Id, internalCurrent?.Id ?? 0, task.Id, TplEventSource.TaskWaitBehavior.Asynchronous, task2?.Id ?? 0);
}
return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (Action<Action, Task>)delegate(Action innerContinuation, Task innerTask)
{
if (Task.s_asyncDebuggingEnabled)
{
Task.RemoveFromActiveTasks(innerTask);
}
TplEventSource log2 = TplEventSource.Log;
Guid oldActivityThatWillContinue = default(Guid);
bool flag = log2.IsEnabled();
if (flag)
{
Task internalCurrent2 = Task.InternalCurrent;
log2.TaskWaitEnd(internalCurrent2?.m_taskScheduler.Id ?? TaskScheduler.Default.Id, internalCurrent2?.Id ?? 0, innerTask.Id);
if (log2.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)1024) != 0)
{
EventSource.SetCurrentThreadActivityId(TplEventSource.CreateGuidForTaskID(innerTask.Id), out oldActivityThatWillContinue);
}
}
innerContinuation();
if (flag)
{
log2.TaskWaitContinuationComplete(innerTask.Id);
if (log2.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)1024) != 0)
{
EventSource.SetCurrentThreadActivityId(oldActivityThatWillContinue);
}
}
}, task);
}
}
public readonly struct TaskAwaiter<TResult> : ICriticalNotifyCompletion, INotifyCompletion, ITaskAwaiter
{
private readonly Task<TResult> m_task;
public bool IsCompleted => m_task.IsCompleted;
internal TaskAwaiter(Task<TResult> task)
{
m_task = task;
}
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);
}
[StackTraceHidden]
public TResult GetResult()
{
TaskAwaiter.ValidateEnd(m_task);
return m_task.ResultOnSuccess;
}
}
// System.Threading.ThreadPool
internal static void UnsafeQueueUserWorkItemInternal(object callBack, bool preferLocal)
{
EnsureInitialized();
ThreadPoolGlobals.workQueue.Enqueue(callBack, !preferLocal);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment