Create a gist now

Instantly share code, notes, and snippets.

Fire and forget with TPL and retry on ASP.NET
Task.Factory.StartNew((state) =>
{
try
{
// use http://nuget.org/packages/TransientFaultHandling.Core
// the defaultfixed strategy retries 10 times every 1 second
RetryPolicy.DefaultFixed.ExecuteAction(() =>
{
// do something that might throw an exception like calling an http endpoint
});
}
catch
{
// if after the 10 retries keeps failing, swallow or log somewhere
}
}, new { RequestUrl = HttpContext.Request.Url } );
// since the HttpContext won't be available by the time the Task executes, send whatever you want (value types) through state as an anonymous object
// depends on: http://nuget.org/packages/TransientFaultHandling.Core and TPL
public static class FireAndForget
{
public static RetryPolicy DefaultRetryPolicy = RetryPolicy.DefaultFixed;
public static void ExecuteWithRetry(Action action)
{
ExecuteWithRetry(action, null, DefaultRetryPolicy);
}
public static void ExecuteWithRetry(Action action, RetryPolicy retryPolicy)
{
ExecuteWithRetry(action, null, retryPolicy);
}
public static void ExecuteWithRetry(Action<object> action, object state)
{
ExecuteWithRetry(action, state, DefaultRetryPolicy);
}
public static void ExecuteWithRetry(Action<object> action, object state, RetryPolicy retryPolicy)
{
ExecuteWithRetry(action, state, null, retryPolicy);
}
public static void ExecuteWithRetry(Action action, Action<Exception> onErrorAfterRetries)
{
ExecuteWithRetry(action, onErrorAfterRetries, DefaultRetryPolicy);
}
public static void ExecuteWithRetry(Action action, Action<Exception> onErrorAfterRetries, RetryPolicy retryPolicy)
{
Task.Factory.StartNew(() =>
{
try
{
retryPolicy.ExecuteAction(() =>
{
action();
});
}
catch (Exception ex)
{
if (onErrorAfterRetries != null)
onErrorAfterRetries(ex);
}
});
}
public static void ExecuteWithRetry(Action<object> action, object state, Action<Exception> onErrorAfterRetries)
{
ExecuteWithRetry(action, state, onErrorAfterRetries, DefaultRetryPolicy);
}
public static void ExecuteWithRetry(Action<object> action, object state, Action<Exception> onErrorAfterRetries, RetryPolicy retryPolicy)
{
Task.Factory.StartNew((taskState) =>
{
try
{
retryPolicy.ExecuteAction(() =>
{
action(taskState);
});
}
catch (Exception ex)
{
if (onErrorAfterRetries != null)
onErrorAfterRetries(ex);
}
}, state);
}
}
// simple fire and forget
FireAndForget.ExecuteWithRetry(() =>
{
// do something that takes a couple of seconds (like calling an http endpoint)
// create an artificial random exception
if (new Random(DateTime.Now.Second).Next(1, 2) == 1)
throw new Exception();
});
// passing state + handling error
FireAndForget.ExecuteWithRetry((state) =>
{
var url = ((dynamic)state).RequestUrl;
// do something that takes a couple of seconds (like calling an http endpoint)
// create an artificial random exception
if (new Random(DateTime.Now.Second).Next(1, 2) == 1)
throw new Exception();
},
state: new { RequestUrl = HttpContext.Request.Url },
onErrorAfterRetries: (exception) =>
{
// log somewhere
});
// you can override the retry policy by setting DefaultRetryPolicy or passing the parameter
@sballarati

awesome! Thanks for sharing, it is very useful for us!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment