多次抛出相同的异常实例

时间:2018-03-28 12:19:25

标签: c# exception-handling

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

private readonly Exception exceptionInstance = new Exception("message");

多次抛出同一个异常实例是否正确?

2 个答案:

答案 0 :(得分:4)

对于各种已经说明的原因,这是不好的做法,但是在多线程代码中它会失败,因为if (std::cin.peek() != '\n') { std::getline(std::cin, s1, '-'); std::cin.putback('-'); } 类(显然)不是线程安全的,并且它不是不可变的。

考虑以下代码:

Exception

这里我们有两个方法class Program { static readonly Exception _test = new Exception("test"); static void Main(string[] args) { ThreadPool.SetMinThreads(10, 8); var random = new Random(); int num1 = 0; int num2 = 0; var tasks = new List<Task>(); for (int i = 0; i < 10; i++) { tasks.Add(Task.Run(() => { try { if (random.Next(0, 2) == 0) { Interlocked.Increment(ref num1); Throw1(); } else { Interlocked.Increment(ref num2); Throw2(); } } catch (Exception ex) { Console.WriteLine(ex); } })); } Task.WaitAll(tasks.ToArray()); Console.WriteLine("num1: " + num1); Console.WriteLine("num2: " + num2); Console.ReadKey(); } static void Throw1() { throw _test; } static void Throw2() { throw _test; } } Throw1(),它们都从私有字段中抛出相同的异常实例。然后我们运行10个线程,随机调用Throw2()Throw1()并打印已抛出的内容。此类代码的输出示例如下:

Throw2()

因此,System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 System.Exception: test в ConsoleApp8.Program.Throw1() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 52 в ConsoleApp8.Program.<>c__DisplayClass1_0.<Main>b__0() в H:\VSProjects\SoHelp\ConsoleApp8\Program.cs:строка 32 num1: 6 num2: 4 被调用了6次而Throw1()被调用了4次 - 我们打印的所有10个堆栈跟踪都引用了Throw2()方法。

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

答案 1 :(得分:3)

没有。不推荐在代码中的多个位置投掷Exception的相同实例(不计算重新计算!)。

异常包含的只是它的消息 - 它包含有用的调试信息,例如堆栈跟踪。 (更新:刚刚测试过。堆栈跟踪可能已添加到throw语句中的异常中,因此它与此答案无关)和TargetSite(来自我的测试,似乎它会在第一次抛出异常时填充,但在此之后再也不会填充。

在代码中的不同位置抛出相同的Exception实例会使您无法使用其中一些数据。