/// <summary> /// Schedules the continuation onto the <see cref="Task" /> associated with this <see cref="TaskAwaiter" /> . /// </summary> /// <param name="task"> The awaited task. </param> /// <param name="continuation"> The action to invoke when the await operation completes. </param> /// <param name="continueOnCapturedContext"> Whether to capture and marshal back to the current context. </param> /// <exception cref="ArgumentNullException"> /// The /// <paramref name="continuation" /> /// argument is null (Nothing in Visual Basic). /// </exception> /// <exception cref="NullReferenceException">The awaiter was not properly initialized.</exception> /// <remarks> /// This method is intended for compiler user rather than use directly in code. /// </remarks> internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext) { if (continuation == null) { throw new ArgumentNullException(nameof(continuation)); } var syncContext = continueOnCapturedContext ? SynchronizationContext.Current : null; if (syncContext != null && syncContext.GetType() != typeof(SynchronizationContext)) { task.ContinueWith ( _ => { try { syncContext.Post(state => ((Action)state)(), continuation); } catch (Exception ex) { AsyncMethodBuilderCore.ThrowOnContext(ex, null); } }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default ); } else { OnCompletedWithoutSyncContext(task, continuation, continueOnCapturedContext); } }
/// <summary> /// Notifies the current synchronization context that the operation completed. /// </summary> private void NotifySynchronizationContextOfCompletion() { try { _synchronizationContext.OperationCompleted(); } catch (Exception ex) { AsyncMethodBuilderCore.ThrowOnContext(ex, null); } }
/// <summary> /// Schedules the continuation onto the <see cref="Task" /> associated with this <see cref="TaskAwaiter" /> . /// </summary> /// <param name="task"> The awaited task. </param> /// <param name="continuation"> The action to invoke when the await operation completes. </param> /// <param name="continueOnCapturedContext"> Whether to capture and marshal back to the current context. </param> /// <exception cref="ArgumentNullException">The /// <paramref name="continuation" /> /// argument is null (Nothing in Visual Basic).</exception> /// <exception cref="NullReferenceException">The awaiter was not properly initialized.</exception> /// <remarks> /// This method is intended for compiler user rather than use directly in code. /// </remarks> internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext) { if (continuation == null) { throw new ArgumentNullException(nameof(continuation)); } var syncContext = continueOnCapturedContext ? SynchronizationContext.Current : null; if (syncContext != null && syncContext.GetType() != typeof(SynchronizationContext)) { task.ContinueWith(result => { try { syncContext.Post(state => ((Action)state)(), continuation); } catch (Exception ex) { AsyncMethodBuilderCore.ThrowOnContext(ex, null); } }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } else { var scheduler = continueOnCapturedContext ? TaskScheduler.Current : TaskScheduler.Default; if (task.IsCompleted) { Task.Factory.StartNew(state => ((Action)state)(), continuation, CancellationToken.None, TaskCreationOptions.None, scheduler); } else if (scheduler != TaskScheduler.Default) { task.ContinueWith(_ => RunNoException(continuation), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, scheduler); } else { task.ContinueWith(result => { if (IsValidLocationForInlining) { RunNoException(continuation); } else { Task.Factory.StartNew(state => RunNoException((Action)state), continuation, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); } }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } } }
public void AwaitUnsafeOnCompleted <TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { try { var completionAction = _coreState.GetCompletionAction(ref this, ref stateMachine); awaiter.UnsafeOnCompleted(completionAction); } catch (Exception ex) { AsyncMethodBuilderCore.ThrowOnContext(ex, null); } }
private static void RunNoException(Action continuation) { if (continuation == null) { return; } try { continuation(); } catch (Exception ex) { AsyncMethodBuilderCore.ThrowOnContext(ex, null); } }
/// <summary> /// Faults the method builder with an exception. /// </summary> /// <param name="exception">The exception that is the cause of this fault.</param> /// <exception cref="ArgumentNullException"> /// The <paramref name="exception" /> argument is null (Nothing in Visual /// Basic). /// </exception> /// <exception cref="InvalidOperationException">The builder is not initialized.</exception> public void SetException(Exception exception) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } if (_synchronizationContext != null) { try { AsyncMethodBuilderCore.ThrowOnContext(exception, _synchronizationContext); } finally { NotifySynchronizationContextOfCompletion(); } } else { AsyncMethodBuilderCore.ThrowOnContext(exception, null); } }