为什么内部异常到达ThreadException处理程序,而不是实际抛出的异常? [英] Why does the inner exception reach the ThreadException handler and not the actual thrown exception?

查看:1937
本文介绍了为什么内部异常到达ThreadException处理程序,而不是实际抛出的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到抛出异常,并在 Application.ThreadException 事件处理程序赶上他们当一些奇怪的行为。



基本上什么下面的示例中发生的是,一个例外是的的BackgroundWorker 的DoWork 事件处理程序抛出。在 RunWorkerCompleted 事件处理程序重新抛出与原来的内部异常的新的异常。



为什么内部异常秀了在 ThreadException 事件处理程序,而不是acutal异常被抛出?如果我没有提供在 RunWorkerCompleted 事件处理内部异常,正确的异常会显示出来。

 使用系统;使用System.Windows.Forms的
;
使用System.ComponentModel;

命名空间WierdExceptionApp
{
类WierdExceptionForm:表
{
BackgroundWorker的工人=新的BackgroundWorker();

公共WierdExceptionForm()
{
worker.DoWork + =新DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted + =新RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}

无效worker_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs E)
{
如果(e.Error!= NULL)
{
罚球新的异常(w​​orker_RunWorkerCompleted,e.Error);
}
}

无效worker_DoWork(对象发件人,DoWorkEventArgs E)
{
抛出新的异常(w​​orker_DoWork);
}

[STAThread]
静态无效的主要()
{
Application.ThreadException + =新System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(新WierdExceptionForm());
}

静态无效Application_ThreadException(对象发件人,System.Threading.ThreadExceptionEventArgs E)
{
MessageBox.Show(e.Exception.Message);
}
}
}


解决方案

的RunWorkerCompleted事件是从BGW线程到UI线程的WF管道,使Control.Invoke()工作编组。本质上,有与由消息循环排空代表的队列。执行此代码,Control.InvokeMarshaledCallbacks(),你会看到它调用堆栈上,有一个赶上(例外)子句来捕获未处理的异常。该条款要求Application.OnThreadException,传递Exception.GetBaseException的值()。



嗯,这解释了为什么你只看到内部异常。为什么做这样有点不清楚。可能是为了切下的UI线程在其他方面,因为真正的例外,从后台线程来非常令人迷惑的代码堆栈帧。


I'm seeing some wierd behaviour when throwing exceptions and catching them in the Application.ThreadException event handler.

Basically whats happening in the sample below is that an exception is thrown in the DoWork event handler of a BackgroundWorker. The RunWorkerCompleted event handler rethrows a new exception with the original as the inner exception.

Why does the inner exception show up in the ThreadException event handler and not the acutal exception being thrown? If I do not provide an inner exception in the RunWorkerCompleted event handler, the correct exception will show up.

using System;
using System.Windows.Forms;
using System.ComponentModel;

namespace WierdExceptionApp
{
    class WierdExceptionForm : Form
    {
        BackgroundWorker worker = new BackgroundWorker();

        public WierdExceptionForm()
        {
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                throw new Exception("worker_RunWorkerCompleted", e.Error);
            }
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            throw new Exception("worker_DoWork");
        }

        [STAThread]
        static void Main()
        {
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            Application.Run(new WierdExceptionForm());
        }

        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message);
        }
   }
}

解决方案

The RunWorkerCompleted event is marshaled from the BGW thread to the UI thread by the WF plumbing that makes Control.Invoke() work. Essentially, there's a queue with delegates that is emptied by the message loop. The code that does this, Control.InvokeMarshaledCallbacks(), you'll see it on the call stack, has a catch (Exception) clause to catch unhandled exceptions. That clause calls Application.OnThreadException, passing the value of Exception.GetBaseException().

Well, that explains why you only see the inner exception. Why it is done this way is a bit unclear. Possibly to slice off the stack frames of the code in the UI thread that are otherwise pretty confusing since the real exception came from the background thread.

这篇关于为什么内部异常到达ThreadException处理程序,而不是实际抛出的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆