// GET: CustomersAsync
        public async Task <ActionResult> Index()
        {
            CustomerViewModel vm = new CustomerViewModel();
            await AsyncServices.GetCustomer(vm);

            return(View(vm));
        }
        /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.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="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
        /// <exception cref="System.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("continuation");
            }
            SynchronizationContext sc = continueOnCapturedContext ? SynchronizationContext.Current : null;

            if (sc != null && sc.GetType() != typeof(SynchronizationContext))
            {
                // When the task completes, post to the synchronization context, or run it inline if we're already in the right place
                task.ContinueWith(delegate
                {
                    try { sc.Post(state => ((Action)state)(), continuation); }
                    catch (Exception exc) { AsyncServices.ThrowAsync(exc, null); }
                }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
            }
            else
            {
                var scheduler = continueOnCapturedContext ? TaskScheduler.Current : TaskScheduler.Default;
                if (task.IsCompleted)
                {
                    Task.Factory.StartNew(
                        s => ((Action)s)(), continuation, CancellationToken.None, TaskCreationOptions.None, scheduler);
                }
                else
                {
                    // NOTE: There is a known rare race here.  For performance reasons, we want this continuation to
                    // execute synchronously when the task completes, but if the task is already completed by the time
                    // we call ContinueWith, we don't want it executing synchronously as part of the ContinueWith call.
                    // If the race occurs, and if the unbelievable happens and it occurs frequently enough to
                    // stack dive, ContinueWith's support for depth checking helps to mitigate this.

                    if (scheduler != TaskScheduler.Default)
                    {
                        // When the task completes, run the continuation in a callback using the correct task scheduler.
                        task.ContinueWith(_ => RunNoException(continuation),
                                          CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, scheduler);
                    }
                    else
                    {
                        // When the task completes, run the continuation in a callback using the correct task scheduler.
                        task.ContinueWith(delegate
                        {
                            if (IsValidLocationForInlining)
                            {
                                RunNoException(continuation);
                            }
                            else
                            {
                                Task.Factory.StartNew(s => RunNoException((Action)s),
                                                      continuation, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
                            }
                        }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                    }
                }
            }
        }
示例#3
0
 /// <summary>
 /// Invokes the delegate in a try/catch that will propagate the exception asynchronously on the thread pool.
 /// </summary>
 /// <param name="continuation"></param>
 private static void RunNoException(Action continuation)
 {
     try
     {
         continuation.Invoke();
     }
     catch (Exception exception)
     {
         AsyncServices.ThrowAsync(exception, null);
     }
 }
示例#4
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">
        /// If <paramref name="continuation"/> is <see langword="null"/>.
        /// </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>
        private static void OnCompletedInternal(AsyncSubject <TResult> task, Action continuation, bool continueOnCapturedContext)
        {
            if (continuation == null)
            {
                throw new ArgumentNullException("continuation");
            }

            SynchronizationContext sc = continueOnCapturedContext ? SynchronizationContext.Current : null;

            if (sc != null && sc.GetType() != typeof(SynchronizationContext))
            {
                task.Subscribe(param0 =>
                {
                    try
                    {
                        sc.Post(state => ((Action)state).Invoke(), continuation);
                    }
                    catch (Exception exception)
                    {
                        AsyncServices.ThrowAsync(exception, null);
                    }
                });//, CancellationToken.None);, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                return;
            }

            IScheduler taskScheduler = Scheduler.ThreadPool;

            if (task.IsCompleted)
            {
                //Task.Factory.StartNew(s => ((Action)s).Invoke(), continuation, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
                continuation();
                return;
            }

            if (taskScheduler != Scheduler.ThreadPool)
            {
                //task.ContinueWith(_ => RunNoException(continuation), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, taskScheduler);
                task.SubscribeOn(taskScheduler).Subscribe(_ => RunNoException(continuation));
                return;
            }

            task.Subscribe(param0 =>
            {
                if (IsValidLocationForInlining)
                {
                    RunNoException(continuation);
                    return;
                }

                //Task.Factory.StartNew(s => RunNoException((Action)s), continuation, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
                continuation();
            });//, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
        }
        /// <summary>
        /// Throws an exception to handle a task that completed in a state other than
        /// <see cref="TaskStatus.RanToCompletion"/>.
        /// </summary>
        /// <param name="task">The task.</param>
        private static void ThrowForNonSuccess(Task task)
        {
            Debug.Assert(task.Status != TaskStatus.RanToCompletion, "Assertion failed: task.Status != TaskStatus.RanToCompletion");

            // Handle whether the task has been canceled or faulted
            switch (task.Status)
            {
            // If the task completed in a canceled state, throw an OperationCanceledException. TaskCanceledException
            // derives from OCE, and by throwing it we automatically pick up the completed task's CancellationToken if
            // it has one, including that CT in the OCE.
            case TaskStatus.Canceled:
                throw new TaskCanceledException(task);

            // If the task faulted, throw its first exception, even if it contained more than one.
            case TaskStatus.Faulted:
                throw AsyncServices.PrepareExceptionForRethrow(task.Exception.InnerException);

            // This should not happen on valid usage.
            default:
                throw new InvalidOperationException(InvalidOperationExceptionTaskNotCompleted);
            }
        }