不像代码分析所描述的那样抛出和保留堆栈跟踪

rhu*_*hes 8 .net c# exception throw .net-4.5

做代码分析给了我CA2200项:

CA2200 Rethrow保留堆栈详细信息'func()'重新捕获捕获的异常并将其明确指定为参数.使用不带参数的'throw',以保留最初引发异常的堆栈位置.

我已经实现了这个建议,但无论如何我似乎都得到了相同的堆栈跟踪.

这是我的测试代码和输出(空格用于给出明显的行号):

第30行的预期错误

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace throw_test
{
    class Program
    {
        static void Main(string[] args)
        {

            try
            {
                try
                {


                    // line 22 below
                    throw new Exception();
                }
                catch (Exception ex) // DEFINES AND THROWS 'ex'
                {



                    // line 30 below
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
            }

            Console.Read();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

在c:\ Users\Richard\Documents\Visual Studio 2013\Projects\using_throw_closestream\using_throw_closestream\Program.cs中的throw_test.Program.Main(String [] args):第30行

第22行的预期错误

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace throw_test
{
    class Program
    {
        static void Main(string[] args)
        {

            try
            {
                try
                {


                    // line 22 below
                    throw new Exception();
                }
                catch (Exception) // NO 'ex'
                {



                    // line 30 below
                    throw;
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
            }

            Console.Read();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

在c:\ Users\Richard\Documents\Visual Studio 2013\Projects\using_throw_closestream\using_throw_closestream\Program.cs中的throw_test.Program.Main(String [] args):第30行

同样的结果.

我的问题

有了其他这样的问题,建议使用更复杂或更明确的方法来保存堆栈跟踪,为什么Code Analysis建议要求我做一些似乎不起作用的事情?

如果这个建议事实上是正确的,我做错了什么?

Ton*_*ony 7

如果你使用.Net 4.5,你可以使用ExceptionDispatchInfo.Capture(ex).Throw();,你会得到一个很好的堆栈跟踪,包括第22行和第30行.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            try
            {
                try
                {


                    // line 22 below
                    throw new Exception();
                }
                catch (Exception ex) // NO 'ex'
                {



                    // line 30 below
                    ExceptionDispatchInfo.Capture(ex).Throw();
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
            }

            Console.Read();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

   at ConsoleApplication1.Program.Main(String[] args) in c:\ConsoleApplication1\Program.cs:line 22
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at ConsoleApplication1.Program.Main(String[] args) in c:\ConsoleApplication1\Program.cs:line 30
Run Code Online (Sandbox Code Playgroud)


rhu*_*hes 5

上面标记是正确的.

只有从另一个方法抛出时才会保留堆栈跟踪.

这里的堆栈跟踪将通过包括抛出的原始错误来保留 Method()

以下代码说明了这一点:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace throw_test
{
    class Program
    {
        static void Main(string[] args)
        {

            try
            {
                try
                {


                    // line 22 below
                    Method();
                }
                catch (Exception ex)
                {



                    // line 30 below
                    throw;
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
            }

            Console.Read();
        }

        public static void Method()
        {
            throw new Exception();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

at c:\ Users\Richard\Documents\Visual Studio 2013\Projects\using_throw_closestream\using_throw_closestream\Program.cs:line 43 at throw_test.Program.Main(String [] args)in c:\用户\ Richard\Documents\Visual Studio 2013\Projects\using_throw_closestream\using_throw_closestream\Program.cs:第30行