你能在另一个线程上重新抛出.NET异常吗?

时间:2009-08-20 01:33:32

标签: c# multithreading exception

在C#中捕获异常并在一个线程上重新抛出是否合法且安全。

E.g。这是合法的

Exception localEx = null;

Thread mythread = new Thread() { () =>
                   {
                        try
                        {
                            DoSomeStuff();
                        }
                        catch(Exception ex)
                        {
                            localEx = ex;
                        }
                    });

myThread.Start();
...
myThread.Join();

if(localEx != null)
   throw localEx;    // rethrow on the main thread

我认为这是合法的,但我很难找到证明它的doco。我找到的最接近的是简要提及在线程之间转移异常:http://msdn.microsoft.com/en-us/library/ms229005.aspx

6 个答案:

答案 0 :(得分:11)

是的,这是合法的。 (一般来说)例外是没有线程关联的描述性对象。

最好在新的异常中包装线程异常:

throw new Exception("Something descriptive here", localEx);

这样,localEx中的堆栈跟踪将被保留(作为新异常的InnerException。)

答案 1 :(得分:3)

你所做的不是重新抛出。这是您碰巧在变量中遇到的异常实例的新内容。即使你只使用一个线程,这也是一个坏主意,因为它使异常看起来像是来自“throw”网站。有多个线程,我不知道有人会发现有一个线程更改。

答案 2 :(得分:3)

绝对。 System.AggregateException被添加到.NET 4中,专门用于并行操作期间。

答案 3 :(得分:2)

我不明白为什么它不起作用,但你需要记住你实际上并没有重新抛出异常。您正在抛出一个新异常,恰好是同一个异常对象。因此,例如,堆栈跟踪会说它是从“throw localEx”抛出的。而不是原始异常的来源。

答案 4 :(得分:2)

这是合法的,它不是重新抛出,它是另一个线程抛出的新异常(具有相同的异常对象)

答案 5 :(得分:0)

我不知道为什么你认为它不合法。如果它是非法的肯定会编译器捕获或运行时将抛出异常。事实上我使用这种模式。 @John在使用后台线程调用Web服务的Windows窗体应用程序中,我使用这种方式。然后在Application.ThreadException顶级处理程序中处理异常,记录等。不必知道发生异常的线程。