Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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

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