// 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); } } } }
/// <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); } }
/// <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); } }