Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Task Extensions
static async Task<T> Otherwise<T> (this Task<T> task, Func<Task<T>> orTask) {
task.ContinueWith (async innerTask => {
if (innerTask.Status == TaskStatus.Faulted)
return await orTask ();
return await Task.FromResult<T> (innerTask.Result);
}).Unwrap ();
static async Task<T> Retry<T> (Func<Task<T>> task, int retries, TimeSpan delay, CancellationToken cts = default (CancellationToken)) {
await task ().ContinueWith (async innerTask => {
cts.ThrowIfCancellationRequested ();
if (innerTask.Status != TaskStatus.Faulted)
return innerTask.Result;
if (retries == 0)
throw innerTask.Exception ??
throw new Exception ();
await Task.Delay (delay, cts);
return await Retry (task, retries - 1, delay, cts);
}).Unwrap ();
// Example:
Image image = await AsyncEx.Retry (async () =>
await DownloadImageAsync ("Bugghina001.jpg").Otherwise (async () =>await DownloadImageAsync ("Bugghina002.jpg")),
5, TimeSpan.FromSeconds (2));
static Task<T> Catch<T, TError> (this Task<T> task, Func<TError, T> onError) where TError : Exception {
var tcs = new TaskCompletionSource<T> ();
task.ContinueWith (innerTask => {
if (innerTask.IsFaulted && innerTask?.Exception?.InnerException is TError)
tcs.SetResult (onError ((TError) innerTask.Exception.InnerException));
else if (innerTask.IsCanceled)
tcs.SetCanceled ();
else if (innerTask.IsFaulted)
tcs.SetException (innerTask?.Exception?.InnerException ??throw new InvalidOperationException ());
tcs.SetResult (innerTask.Result);
return tcs.Task;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment