Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 ///     Notifies the current synchronization context that the operation completed.
 /// </summary>
 private void NotifySynchronizationContextOfCompletion()
 {
     try
     {
         _synchronizationContext.OperationCompleted();
     }
     catch (Exception ex)
     {
         AsyncMethodBuilderCore.ThrowOnContext(ex, null);
     }
 }
Ejemplo n.º 3
0
        /// <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);
                }
            }
        }
Ejemplo n.º 4
0
 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);
     }
 }
Ejemplo n.º 5
0
 private static void RunNoException(Action continuation)
 {
     if (continuation == null)
     {
         return;
     }
     try
     {
         continuation();
     }
     catch (Exception ex)
     {
         AsyncMethodBuilderCore.ThrowOnContext(ex, null);
     }
 }
Ejemplo n.º 6
0
        /// <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);
            }
        }