面对生成一个异常实例然后可能多次抛出该异常的代码。
private readonly Exception exceptionInstance = new Exception("message");
Run Code Online (Sandbox Code Playgroud)
多次抛出相同的异常实例是否正确?
由于各种已经陈述的原因,这是一种不好的做法,但在多线程代码中它会失败,因为Exception类(显然)不是线程安全的,并且它不是不可变的。
考虑这段代码:
\n\nclass 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}\nRun Code Online (Sandbox Code Playgroud)\n\n这里我们有 2 个方法,Throw1()它们Throw2()都从私有字段抛出相同的异常实例。然后我们运行 10 个线程,它们要么随机调用,Throw1()要么Throw2()随机打印并打印抛出的内容。此类代码的示例输出是:
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\nRun Code Online (Sandbox Code Playgroud)\n\n因此,虽然Throw1()已被调用 6 次,并且Throw2()已被调用 4 次 - 我们打印的所有 10 个堆栈跟踪都引用了Throw1()方法。
所以永远不要这样做,因为绝对没有理由这样做。
\n