Task <T> Execute(Task <T> task, Func <T, Task <T> > continuationTask, ExecuteOptions options) { if (task.IsCompleted && options.HasFlag(ExecuteOptions.RunSynchronously)) { if (task.IsFaulted) { return(TaskUtil.Faulted <T>(task.Exception.InnerExceptions)); } if (task.IsCanceled || _cancellationToken.IsCancellationRequested) { return(TaskUtil.Canceled <T>()); } if (task.Status == TaskStatus.RanToCompletion) { try { return(continuationTask(task.Result)); } catch (Exception ex) { return(TaskUtil.Faulted <T>(ex)); } } } return(ExecuteAsync(task, continuationTask, options)); }
Task <T> ExecuteAsync(Task <T> task, Func <T, Task <T> > continuationTask, ExecuteOptions options) { var source = new TaskCompletionSource <Task <T> >(); task.ContinueWith((Task <T> innerTask) => { if (innerTask.IsFaulted) { source.TrySetException(innerTask.Exception.InnerExceptions); } else if (innerTask.IsCanceled || _cancellationToken.IsCancellationRequested) { source.TrySetCanceled(); } else { try { source.TrySetResult(continuationTask(innerTask.Result)); } catch (Exception ex) { source.TrySetException(ex); } } }, options.HasFlag(ExecuteOptions.RunSynchronously) ? TaskContinuationOptions.ExecuteSynchronously : TaskContinuationOptions.None); return(source.Task.FastUnwrap()); }
Composer <T> Composer <T> .Finally(Action <T, TaskStatus> continuation, ExecuteOptions options) { if (_task.IsCompleted && options.HasFlag(ExecuteOptions.RunSynchronously)) { continuation(_payload, _task.Status); return(this); } _task = FinallyAsync(_task, continuation, options); return(this); }
Task <T> FinallyAsync(Task <T> task, Action <T, TaskStatus> continuation, ExecuteOptions options) { var source = new TaskCompletionSource <T>(); task.ContinueWith((Task <T> innerTask) => { try { continuation(_payload, innerTask.Status); source.TrySetFromTask(innerTask); } catch (Exception ex) { source.TrySetException(ex); } }, options.HasFlag(ExecuteOptions.RunSynchronously) ? TaskContinuationOptions.ExecuteSynchronously : TaskContinuationOptions.None); return(source.Task); }