public void TryGetResult_FaultedTask_ReturnsFalse() { // Arrange var task = TaskHelpers.FromError <int>(new Exception()); // Act int value; bool result = task.TryGetResult(out value); // Assert Assert.False(result); var ex = task.Exception; // Observe the task exception }
internal static Task <TOuterResult> CastFromObject <TOuterResult>(this Task <object> task) { // Stay on the same thread if we can if (task.IsCompleted) { if (task.IsFaulted) { return(TaskHelpers.FromErrors <TOuterResult>(task.Exception.InnerExceptions)); } if (task.IsCanceled) { return(TaskHelpers.Canceled <TOuterResult>()); } if (task.Status == TaskStatus.RanToCompletion) { try { return(TaskHelpers.FromResult((TOuterResult)task.Result)); } catch (Exception exception) { return(TaskHelpers.FromError <TOuterResult>(exception)); } } } var tcs = new TaskCompletionSource <TOuterResult>(); // schedule a synchronous task to cast: no need to worry about sync context or try/catch task.ContinueWith(innerTask => { if (innerTask.IsFaulted) { tcs.SetException(innerTask.Exception.InnerExceptions); } else if (innerTask.IsCanceled) { tcs.SetCanceled(); } else { try { tcs.SetResult((TOuterResult)innerTask.Result); } catch (Exception exception) { tcs.SetException(exception); } } }, TaskContinuationOptions.ExecuteSynchronously); return(tcs.Task); }
internal static Task Iterate(IEnumerable <Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken), bool disposeEnumerator = true, Func <Task, bool> breakCondition = null) { IEnumerator <Task> enumerator = null; try { enumerator = asyncIterator.GetEnumerator(); Task task = IterateImpl(enumerator, cancellationToken, breakCondition); return((disposeEnumerator && enumerator != null) ? task.Finally(enumerator.Dispose, runSynchronously: true) : task); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
public Task ConvertFromFaultedTaskOfObjectShouldBeHandled() { // Arrange return(TaskHelpers.FromError <object>(new InvalidOperationException()) // Act .CastToObject() // Assert .ContinueWith((task) => { Assert.Equal(TaskStatus.Faulted, task.Status); Assert.IsType <InvalidOperationException>(task.Exception.GetBaseException()); })); }
public static Task Iterate(IEnumerable <Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken), bool disposeEnumerator = true) { Contract.Assert(asyncIterator != null); try { var enumerator = asyncIterator.GetEnumerator(); var task = IterateImpl(enumerator, cancellationToken); return((disposeEnumerator) ? task.Finally(enumerator.Dispose, true) : task); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
internal static Task Iterate(IEnumerable <Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken)) { Contract.Assert(asyncIterator != null); IEnumerator <Task> enumerator = null; try { enumerator = asyncIterator.GetEnumerator(); Task task = IterateImpl(enumerator, cancellationToken); return((enumerator != null) ? task.Finally(enumerator.Dispose) : task); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
private static Task IterateImpl(IEnumerator <Task> enumerator, CancellationToken cancellationToken, Func <Task, bool> breakCondition) { try { while (true) { // short-circuit: iteration canceled if (cancellationToken.IsCancellationRequested) { return(TaskHelpers.Canceled()); } // short-circuit: iteration complete if (!enumerator.MoveNext()) { return(TaskHelpers.Completed()); } // fast case: Task completed synchronously & successfully Task currentTask = enumerator.Current; if (currentTask.Status == TaskStatus.RanToCompletion) { if (breakCondition != null && breakCondition(currentTask)) { return(currentTask); } continue; } // fast case: Task completed synchronously & unsuccessfully if (currentTask.IsCanceled || currentTask.IsFaulted) { return(currentTask); } // slow case: Task isn't yet complete return(IterateImplIncompleteTask(enumerator, currentTask, cancellationToken, breakCondition)); } } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
public static Task Finally(this Task task, Action continuation, bool runSynchronously = false) { if (task.IsCompleted) { try { continuation(); return(task); } catch (Exception ex) { MarkExceptionsObserved(task); return(TaskHelpers.FromError(ex)); } } return(FinallyImplContinuation <AsyncVoid>(task, continuation, runSynchronously)); }
internal static Task <TResult> Finally <TResult>(this Task <TResult> task, Action continuation, bool runSynchronously = false) { // Stay on the same thread if we can if (task.IsCompleted) { try { continuation(); return(task); } catch (Exception ex) { MarkExceptionsObserved(task); return(TaskHelpers.FromError <TResult>(ex)); } } // Split into a continuation method so that we don't create a closure unnecessarily return(FinallyImplContinuation <TResult>(task, continuation, runSynchronously)); }
internal static Task Finally(this Task task, Action continuation) { // Stay on the same thread if we can if (task.IsCompleted) { try { continuation(); return(task); } catch (Exception ex) { MarkExceptionsObserved(task); return(TaskHelpers.FromError(ex)); } } // Split into a continuation method so that we don't create a closure unnecessarily return(FinallyImplContinuation <AsyncVoid>(task, continuation)); }
public static Tasks.Task Iterate(IEnumerable <Tasks.Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken), bool disposeEnumerator = true) { if (asyncIterator == null) { throw new ArgumentNullException("asyncIterator"); } IEnumerator <Tasks.Task> enumerator = null; try { enumerator = asyncIterator.GetEnumerator(); Tasks.Task task = IterateImpl(enumerator, cancellationToken); return((disposeEnumerator && enumerator != null) ? task.Finally(enumerator.Dispose, runSynchronously: true) : task); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
private static Task <TResult> CatchImpl <TResult>(this Task task, Func <Task <TResult> > continuation, CancellationToken cancellationToken) { // Stay on the same thread if we can if (task.IsCompleted) { if (task.IsFaulted) { try { Task <TResult> resultTask = continuation(); if (resultTask == null) { // Not a resource because this is an internal class, and this is a guard clause that's intended // to be thrown by us to us, never escaping out to end users. throw new InvalidOperationException("You must set the Task property of the CatchInfo returned from the TaskHelpersExtensions.Catch continuation."); } return(resultTask); } catch (Exception ex) { return(TaskHelpers.FromError <TResult>(ex)); } } if (task.IsCanceled || cancellationToken.IsCancellationRequested) { return(TaskHelpers.Canceled <TResult>()); } if (task.Status == TaskStatus.RanToCompletion) { TaskCompletionSource <TResult> tcs = new TaskCompletionSource <TResult>(); tcs.TrySetFromTask(task); return(tcs.Task); } } // Split into a continuation method so that we don't create a closure unnecessarily return(CatchImplContinuation(task, continuation)); }
public CatchResult Throw(Exception ex) { return(new CatchResult { Task = TaskHelpers.FromError <object>(ex) }); }