首页 > 解决方案 > C# 异常处理 - 最后一个 catch 块获取是否会重新抛出异常?

问题描述

我想知道这段代码是否会以在 10 次重试后被CleanUp()调用的方式工作?还是throw new Exception()不会被最后一个 catch 块捕获?

public void Process()
{
    try
    {}
    catch (MyException e)
    {           
        int retries = GetRetries();
        if(retries > 10)
        {
            _logger.LogError("Retried event already {retries} times. Giving up.", retries);
            throw new Exception("Giving up!");
        }

        Process();

    }
    catch (Exception e)
    {
        CleanUp();
    }
}

标签: c#exception

解决方案


不,它不是那样工作的。对于任何给定的try/catch块,只有源自于的异常try才能被相应的catch块捕获。块内抛出的异常不能被同一级别catch的其他块捕获。catch

finally块允许您在控制出于任何原因离开try/时运行代码。因此,如果您的末尾已经有 a那么您只需将您的 final 更改为并删除部分末尾的 the 。catchtryCleanUpcatch(Exception e)finallyCleanUptry

但是,如果您只想在控制通过异常CleanUp离开try/时运行,那么您就没有那么幸运了。IL 中有一个子句,即,但仅用于异常,但在 C# 中未公开。catch faultfinally

因此,如果您需要它,通常最好引入一个额外的bool,表明您try毫无例外地到达了块的末尾,并使用它来使您的CleanUp调用在finally.


或者你可以通过嵌套/块来模拟try// :catchfaulttrycatch

try
{
    try
    {}
    catch (MyException e)
    {           
        int retries = GetRetries();
        if(retries > 10)
        {
            _logger.LogError("Retried event already {retries} times. Giving up.", retries);
            throw new Exception("Giving up!");
        }

        Process();

    }
}
catch
{
  //Act as fault
  CleanUp();
  throw;
}

推荐阅读