为什么内部异常到达ThreadException处理程序而不是实际抛出的异常?

时间:2008-12-07 11:55:19

标签: c# winforms multithreading exception-handling

在抛出异常并在Application.ThreadException事件处理程序中捕获它们时,我看到了一些奇怪的行为。

基本上,下面示例中发生的事件是DoWork的{​​{1}}事件处理程序中抛出异常。 BackgroundWorker事件处理程序重新抛出一个新异常,原始异常作为内部异常。

为什么内部异常出现在RunWorkerCompleted事件处理程序中而不是抛出的实际异常?如果我没有在ThreadException事件处理程序中提供内部异常,则会显示正确的异常。

RunWorkerCompleted

2 个答案:

答案 0 :(得分:10)

RunWorkerCompleted事件由WW管道从BGW线程封送到UI线程,使得Control.Invoke()工作。本质上,有一个队列,其中的代理由消息循环清空。执行此操作的代码Control.InvokeMarshaledCallbacks(),您将在调用堆栈上看到它,它有一个catch(Exception)子句来捕获未处理的异常。该子句调用Application.OnThreadException,传递Exception.GetBaseException()的值。

嗯,这就解释了为什么你只看到内部异常。为什么这样做有点不清楚。可能会切断UI线程中代码的堆栈帧,否则会很困惑,因为真正的异常来自后台线程。

答案 1 :(得分:0)

        if (e.Error != null)
        {
            throw new Exception("worker_RunWorkerCompleted", new Exception("Inner", new Exception("Inner inner")));
        }

你最终会得到“内心”。看来这是Application_ThreadException方法的行为,用于查看最内层的异常。