gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:10:30 29 4
gpt4 key购买 nike

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

基本上下面示例中发生的事情是在 BackgroundWorkerDoWork 事件处理程序中抛出异常。 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);
}
}
}

最佳答案

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

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

关于c# - 为什么内部异常到达 ThreadException 处理程序而不是实际抛出的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/347502/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com