All the service calls in my application are implemented as tasks.When ever a task is faulted ,I need to present the user with a dialog box to retry the last operation failed
Here's a riffed version of Panagiotis Kanavos's excellent answer which I've tested and am using in production.
It addresses some things that were important to me:
async
(less environment constraints)Exception
in the case of failure include details from each attemptstatic Task RetryWhile(
Func> func,
Func shouldRetry )
{
return RetryWhile( func, shouldRetry, new TaskCompletionSource(), 0, Enumerable.Empty() );
}
static Task RetryWhile(
Func> func,
Func shouldRetry,
TaskCompletionSource tcs,
int previousAttempts, IEnumerable previousExceptions )
{
func( previousAttempts ).ContinueWith( antecedent =>
{
if ( antecedent.IsFaulted )
{
var antecedentException = antecedent.Exception;
var allSoFar = previousExceptions
.Concat( antecedentException.Flatten().InnerExceptions );
if ( shouldRetry( antecedentException, previousAttempts ) )
RetryWhile( func,shouldRetry,previousAttempts+1, tcs, allSoFar);
else
tcs.SetException( allLoggedExceptions );
}
else
tcs.SetResult( antecedent.Result );
}, TaskContinuationOptions.ExecuteSynchronously );
return tcs.Task;
}