面对生成一个异常实例的代码,然后可能多次抛出它。
private readonly Exception exceptionInstance = new Exception("message");
多次抛出同一个异常实例是否正确?
答案 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
实例会使您无法使用其中一些数据。