Retry a task multiple times based on user input in case of an exception in task

后端 未结 3 1689
甜味超标
甜味超标 2020-11-27 05:29

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

3条回答
  •  無奈伤痛
    2020-11-27 06:29

    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:

    • Want to be able to decide whether to retry based on number of preceding attempts and exception from current attempt
    • Don't want to rely on async (less environment constraints)
    • Want to have the resulting Exception in the case of failure include details from each attempt


    static 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;
    }
    

提交回复
热议问题