我如何将其形式化为更通用,我可以在其中指定要抛出的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();
答案 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
}