Task <T> CompensateAsync(Task <T> task, Func <Task <T>, Task <T> > compensationTask) { var source = new TaskCompletionSource <Task <T> >(); task.ContinueWith((Task <T> innerTask) => { if (innerTask.IsCanceled) { return(source.TrySetCanceled()); } return(source.TrySetResult(TaskUtil.Completed(innerTask.Result))); }, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.ExecuteSynchronously); task.ContinueWith((Task <T> innerTask) => { try { Task <T> resultTask = compensationTask(innerTask); if (resultTask == null) { throw new InvalidOperationException("Sure could use a Task here buddy"); } source.TrySetResult(resultTask); } catch (Exception ex) { source.TrySetException(ex); } }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously); return(source.Task.FastUnwrap()); }
public TaskComposer(T payload, CancellationToken cancellationToken = default(CancellationToken)) { _payload = payload; _cancellationToken = cancellationToken; _task = cancellationToken.IsCancellationRequested ? TaskUtil.Canceled <T>() : TaskUtil.Completed(payload); }
CompensationResult <T> Compensation <T> .Handled(T payload) { return(new Result(TaskUtil.Completed(payload))); }