首页 > 解决方案 > C#:从变量中重新抛出异常,同时保留堆栈跟踪

问题描述

在我的代码库中,我有一些重试功能,将异常存储在变量中,最后在变量中抛出异常。想象这样的事情

Exception exc = null;

while(condition){
   try {
      // stuff
   } catch (Exception e){
     exc = e;
   }
}

if (e != null){
   throw e;
}

现在,由于这是一个throw e语句而不是throw语句,原始堆栈跟踪丢失了。是否有某种方法可以进行重新抛出以保留原始堆栈跟踪,或者我是否需要重组我的代码以便我可以使用throw语句?

标签: c#exception

解决方案


这就是ExceptionDispatchInfo发挥作用的地方。
它位于System.Runtime.ExceptionServices命名空间内。

class Program
{
    static void Main(string[] args)
    {
        ExceptionDispatchInfo edi = null;

        try
        {
            // stuff
            throw new Exception("A");
        }
        catch (Exception ex)
        {
            edi = ExceptionDispatchInfo.Capture(ex);
        }

        edi?.Throw();
    }
}

输出:

Unhandled exception. System.Exception: A
   at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 16
--- End of stack trace from previous location where exception was thrown ---
   at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 24
  • 第 16 行throw new Exception("A");是调用的地方
  • 第 24 行edi?.Throw();是调用的地方

推荐阅读