如何改进此异常重试方案?

JL.*_*JL. 22 .net c# exception-handling

我有一个我正在调用的Web服务方法,它是第三方和我的域之外.由于某种原因,Web服务偶尔会出现网关超时.它的间歇性和在尝试失败后直接调用它可以成功.

现在我有一个编码困境,我有代码应该做的伎俩,但代码看起来像业余时间,你会在下面看到.

这是非常糟糕的代码,还是可以接受的?如果不能接受,我该如何改进呢?

在看的同时请努力保持笔直.

try
{
    MDO = OperationsWebService.MessageDownload(MI);
}
catch
{
    try
    {
        MDO = OperationsWebService.MessageDownload(MI);
    }
    catch
    {
        try
        {
            MDO = OperationsWebService.MessageDownload(MI);
        }
        catch
        {
            try
            {
                MDO = OperationsWebService.MessageDownload(MI);
            }
            catch 
            {
                try
                {
                    MDO = OperationsWebService.MessageDownload(MI);
                }
                catch (Exception ex)
                {
                    // 5 retries, ok now log and deal with the error.
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*eff 21

你可以循环完成.

Exception firstEx = null;
for(int i=0; i<5; i++) 
{
    try
    {
        MDO = OperationsWebService.MessageDownload(MI);
        firstEx = null;
        break; 
    }
    catch(Exception ex)
    {
        if (firstEx == null) 
        {
            firstEx = ex;
        }
        Thread.Sleep(100 * (i + 1));
    }
}
if (firstEx != null) 
{
    throw new Exception("WebService call failed after 5 retries.", firstEx);
}
Run Code Online (Sandbox Code Playgroud)


duf*_*ymo 12

这是您尝试的另一种方式:

// Easier to change if you decide that 5 retries isn't right for you
Exception exceptionKeeper = null;
for (int i = 0; i < MAX_RETRIES; ++i)
{
    try
    {
       MDO = OperationsWebService.MessageDownload(MI);
       break;  // correct point from Joe - thanks.
    }
    catch (Exception ex)
    {
        exceptionKeeper = ex;
        // 5 retries, ok now log and deal with the error.
    }  
}
Run Code Online (Sandbox Code Playgroud)

我认为它更好地记录了意图.代码也少; 更容易维护.


Joh*_*ers 11

到目前为止,所有答案都假设对任何异常的反应应该是重试操作.这是一个很好的假设,直到它是一个错误的假设.您可以轻松地重试损坏系统的操作,因为您没有检查异常类型.

你几乎应该使用裸露的" catch",也不应该使用" catch (Exception ex)."捕获一个更具体的例外 - 你知道可以安全恢复的例外.

  • @jdk:如果他知道这是一个通信问题,他应该捕获`CommunicationsException`和`TimeoutException`,而不是'Exception`. (4认同)