多次抛出相同的异常实例

gab*_*bba 4 c# exception

面对生成一个异常实例然后可能多次抛出该异常的代码。

private readonly Exception exceptionInstance = new Exception("message");
Run Code Online (Sandbox Code Playgroud)

多次抛出相同的异常实例是否正确?

Evk*_*Evk 5

由于各种已经陈述的原因,这是一种不好的做法,但在多线程代码中它会失败,因为Exception类(显然)不是线程安全的,并且它不是不可变的。

\n\n

考虑这段代码:

\n\n
class Program {\n    static readonly Exception _test = new Exception("test");\n\n    static void Main(string[] args) {\n        ThreadPool.SetMinThreads(10, 8);\n        var random = new Random();\n        int num1 = 0;\n        int num2 = 0;\n        var tasks = new List<Task>();\n        for (int i = 0; i < 10; i++) {\n            tasks.Add(Task.Run(() => {\n                try {\n                    if (random.Next(0, 2) == 0) {\n                        Interlocked.Increment(ref num1);\n                        Throw1();\n                    }\n                    else {\n                        Interlocked.Increment(ref num2);\n                        Throw2();\n                    }\n                }\n                catch (Exception ex) {\n                    Console.WriteLine(ex);\n                }\n            }));\n        }\n\n        Task.WaitAll(tasks.ToArray());\n        Console.WriteLine("num1: " + num1);\n        Console.WriteLine("num2: " + num2);\n        Console.ReadKey();\n    }\n\n    static void Throw1() {\n        throw _test;\n    }\n\n    static void Throw2() {\n        throw _test;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里我们有 2 个方法,Throw1()它们Throw2()都从私有字段抛出相同的异常实例。然后我们运行 10 个线程,它们要么随机调用,Throw1()要么Throw2()随机打印并打印抛出的内容。此类代码的示例输出是:

\n\n
System.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nSystem.Exception: test\n   \xd0\xb2 ConsoleApp8.Program.Throw1() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 52\n   \xd0\xb2 ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() \xd0\xb2 H:\\VSProjects\\SoHelp\\ConsoleApp8\\Program.cs:\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0 32\nnum1: 6\nnum2: 4\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,虽然Throw1()已被调用 6 次,并且Throw2()已被调用 4 次 - 我们打印的所有 10 个堆栈跟踪都引用了Throw1()方法。

\n\n

所以永远不要这样做,因为绝对没有理由这样做。

\n