当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么内部异常到达ThreadException处理程序而不是实际抛出的异常?》经验,为你挑选了1个好方法。

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

基本上下面的示例中发生的是在a的DoWork事件处理程序中抛出异常BackgroundWorker.该RunWorkerCompleted事件处理程序重新抛出与原来的内部异常的新的异常.

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

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);
        }
   }
}

Hans Passant.. 10

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

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



1> Hans Passant..:

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

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


然而*WinForms中的另一个*错误是微软最不确定的!
推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有