internal static Task <object> CastToobject <T>(this Task <T> task) { // Stay on the same thread if we can if (task.IsCompleted) { if (task.IsFaulted) { return(TaskHelpers.FromErrors <object>(task.Exception.InnerExceptions)); } if (task.IsCanceled) { return(TaskHelpers.Canceled <object>()); } if (task.Status == TaskStatus.RanToCompletion) { return(TaskHelpers.FromResult <object>((object)task.Result)); } } TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(); // 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 { tcs.SetResult((object)innerTask.Result); } }, TaskContinuationOptions.ExecuteSynchronously); return(tcs.Task); }
public static Task <object> CastToObject <T>(this Task <T> task) { if (task.IsCompleted) { if (task.IsFaulted) { return(TaskHelpers.FromErrors <object>(task.Exception.InnerExceptions)); } if (task.IsCanceled) { return(TaskHelpers.Canceled <object>()); } if (task.Status == TaskStatus.RanToCompletion) { return(TaskHelpers.FromResult((object)task.Result)); } } var tcs = new TaskCompletionSource <object>(); task.ContinueWith(innerTask => { if (innerTask.IsFaulted) { tcs.SetException(innerTask.Exception.InnerExceptions); } else if (innerTask.IsCanceled) { tcs.SetCanceled(); } else { tcs.SetResult(innerTask.Result); } }, TaskContinuationOptions.ExecuteSynchronously); return(tcs.Task); }
internal static bool TrySetFromTask <TResult>(this TaskCompletionSource <Task <TResult> > tcs, Task source) { if (source.Status == TaskStatus.Canceled) { return(tcs.TrySetCanceled()); } if (source.Status == TaskStatus.Faulted) { return(tcs.TrySetException(source.Exception.InnerExceptions)); } if (source.Status == TaskStatus.RanToCompletion) { // Sometimes the source task is Task<Task<TResult>>, and sometimes it's Task<TResult>. // The latter usually happens when we're in the middle of a sync-block postback where // the continuation is a function which returns Task<TResult> rather than just TResult, // but the originating task was itself just Task<TResult>. An example of this can be // found in TaskExtensions.CatchImpl(). Task <Task <TResult> > taskOfTaskOfResult = source as Task <Task <TResult> >; if (taskOfTaskOfResult != null) { return(tcs.TrySetResult(taskOfTaskOfResult.Result)); } Task <TResult> taskOfResult = source as Task <TResult>; if (taskOfResult != null) { return(tcs.TrySetResult(taskOfResult)); } return(tcs.TrySetResult(TaskHelpers.FromResult(default(TResult)))); } return(false); }
internal static Task <TOuterResult> Then <TInnerResult, TOuterResult>(this Task <TInnerResult> task, Func <TInnerResult, TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken), bool runSynchronously = false) { return(task.ThenImpl(t => TaskHelpers.FromResult(continuation(t.Result)), cancellationToken, runSynchronously)); }
/// <summary> /// Calls the given continuation, after the given task has completed, if the task successfully ran /// to completion (i.e., was not cancelled and did not fault). /// </summary> internal static Task <TOuterResult> Then <TOuterResult>(this Task task, Func <TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken)) { return(task.ThenImpl(t => TaskHelpers.FromResult(continuation()), cancellationToken)); }
// <summary> // Calls the given continuation, after the given task has completed, if the task successfully ran // to completion (i.e., was not cancelled and did not fault). // </summary> internal static Task <TOuterResult> Then <TOuterResult>(this Task task, Func <TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken), bool runSynchronously = false, bool continueOnCapturedContext = true) { return(task.ThenImpl(t => TaskHelpers.FromResult(continuation()), cancellationToken, runSynchronously, continueOnCapturedContext)); }