C#:从变量重新抛出异常,同时保留堆栈跟踪

MrZ*_*arq 3 .net c# exception

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

Exception exc = null;

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

if (e != null){
   throw e;
}
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*ala 8

这就是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)
  • 16号线是throw new Exception("A");叫的地方
  • 第 24 行是edi?.Throw();调用的地方