public void Start <TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => AsyncMethodBuilderCore.Start(ref stateMachine);
/// <summary>Associates the builder with the state machine it represents.</summary> /// <param name="stateMachine">The heap-allocated state machine object.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception> /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception> public void SetStateMachine(IAsyncStateMachine stateMachine) { AsyncMethodBuilderCore.SetStateMachine(stateMachine, m_moveNextAction); // argument validation handled by AsyncMethodBuilderCore }
/// <summary> /// Outputs a WaitBegin ETW event, and augments the continuation action to output a WaitEnd ETW event. /// </summary> /// <param name="task">The task being awaited.</param> /// <param name="continuation">The action to invoke when the await operation completes.</param> /// <returns>The action to use as the actual continuation.</returns> private static Action OutputWaitEtwEvents(Task task, Action continuation) { Contract.Requires(task != null, "Need a task to wait on"); Contract.Requires(continuation != null, "Need a continuation to invoke when the wait completes"); if (Task.s_asyncDebuggingEnabled) { Task.AddToActiveTasks(task); } #if !MONO var etwLog = TplEtwProvider.Log; if (etwLog.IsEnabled()) { // ETW event for Task Wait Begin var currentTaskAtBegin = Task.InternalCurrent; // If this task's continuation is another task, get it. var continuationTask = AsyncMethodBuilderCore.TryGetContinuationTask(continuation); etwLog.TaskWaitBegin( (currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id), (currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0), task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous, (continuationTask != null ? continuationTask.Id : 0), System.Threading.Thread.GetDomainID()); } #endif // Create a continuation action that outputs the end event and then invokes the user // provided delegate. This incurs the allocations for the closure/delegate, but only if the event // is enabled, and in doing so it allows us to pass the awaited task's information into the end event // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred). return(AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, () => { if (Task.s_asyncDebuggingEnabled) { Task.RemoveFromActiveTasks(task.Id); } #if !MONO // ETW event for Task Wait End. Guid prevActivityId = new Guid(); bool bEtwLogEnabled = etwLog.IsEnabled(); if (bEtwLogEnabled) { var currentTaskAtEnd = Task.InternalCurrent; etwLog.TaskWaitEnd( (currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler.Id : TaskScheduler.Default.Id), (currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0), task.Id); // Ensure the continuation runs under the activity ID of the task that completed for the // case the antecendent is a promise (in the other cases this is already the case). if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0) { EventSource.SetCurrentThreadActivityId(TplEtwProvider.CreateGuidForTaskID(task.Id), out prevActivityId); } } #endif // Invoke the original continuation provided to OnCompleted. continuation(); #if !MONO if (bEtwLogEnabled) { etwLog.TaskWaitContinuationComplete(task.Id); if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0) { EventSource.SetCurrentThreadActivityId(prevActivityId); } } #endif })); }
/// <summary>Associates the builder with the specified state machine.</summary> /// <param name="stateMachine">The state machine instance to associate with the builder.</param> public void SetStateMachine(IAsyncStateMachine stateMachine) => AsyncMethodBuilderCore.SetStateMachine(stateMachine, task: null);
public void Start <TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { // Should not be static AsyncMethodBuilderCore.Start(ref stateMachine); }
public void Start <TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => // will provide the right ExecutionContext semantics AsyncMethodBuilderCore.Start(ref stateMachine);