尝试并重试

时间:2018-03-27 19:02:58

标签: c#

我如何将其形式化为更通用,我可以在其中指定要抛出的X异常和X异常,以便在提高代码可读性的同时再次尝试。

private const int RetrySegmentCount = 3;
private const int SecondsBetweenRetry = 30;
var retryCounter = 0;

while (true)
{
    try
    {
        ExecuteProcessThatMayThrow();
        break;
    }
    catch (NotSupportedException) // Do no retry if this is thrown
    {
        throw;
    }
    catch (Exception)
    {
        if (retryCounter < RetrySegmentCount)
        {
            retryCounter++;
            Thread.Sleep(SecondsBetweenRetry * 1000);
        }
        else
        {
            throw;
        }
    }
}

puesdocode中的理想语法可能是

Repeat(3, 30, [NotSupportedException], [Exception]) => ExecuteProcessThatMayThrow();

Repeat(3, 30) => ExecuteProcessThatMayThrow(); //这将在所有

上重复

Repeat(3, 30, [NotSupportedException, VeryBadException], [RetryableException]) => ExecuteProcessThatMayThrow();

1 个答案:

答案 0 :(得分:2)

您可以根据错误类型创建具有多个结果的可重用方法。这是我使用的小修改版本

此方法处理不同的条件并重试

public static bool TryExecute(Action action, int retry, int secondBeforeRetry, List<Type> notSupportedExceptions, List<Type> veryBadExceptions, List<Type> retryableExceptions)
    {
        var success = false;

        // keep trying to run the action
        for (int i = 0; i < retry; i++)
        {
            try
            {
                // run action
                action.Invoke();

                // if it reached here it was successful
                success = true;

                // break the loop
                break;
            }
            catch (Exception ex)
            {
                // if the exception is not retryable
                if (!retryableExceptions.Contains(ex.GetType()))
                {
                    // if its a not supported exception
                    if (notSupportedExceptions.Contains(ex.GetType()))
                    {
                        throw new Exception("No supported");
                    }
                    else if (veryBadExceptions.Contains(ex.GetType()))
                    {
                        throw new Exception("Very bad");
                    }
                }
                else
                {
                    System.Threading.Thread.Sleep(secondBeforeRetry * 1000);
                }
            }
        }

        return success;
    }

要非常简单地调用此方法,因为它们都可以轻松更改为可选参数。这是例子:

    // sample action that force an error to be thrown
    var a = new Action(() =>
    {
        var test = "";
        var test2 = test[3]; // throw out of range exception
    });

    try
    {
        var success = TryExecute(a, 5, 30, new List<Type>() { typeof(IndexOutOfRangeException) }, new List<Type>(), new List<Type>());
    }
    catch (Exception ex)
    {
        // handle whatever you want
    }