Control.Invoke取消包装外部异常并传播内部异常 [英] Control.Invoke unwraps the outer exception and propagates the inner exception instead

查看:90
本文介绍了Control.Invoke取消包装外部异常并传播内部异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的MessageBox.Show调用显示内部".这是一个错误吗?

The MessageBox.Show call below shows "Inner". Is this a bug?

private void Throw()
{
    Invoke(new Action(() =>
    {
        throw new Exception("Outer", new Exception("Inner"));
    }));
}

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        Throw();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message); // Shows "Inner"
    }
}

推荐答案

我看了System.Windows.Forms.Control的参考源,处理Invoke的代码如下:

I had a look at the reference source for System.Windows.Forms.Control, and the code that deals with Invoke looks like this:

try {
    InvokeMarshaledCallback(current);
}
catch (Exception t) {
    current.exception = t.GetBaseException();
}

GetBaseException:

public virtual Exception GetBaseException() 
{
    Exception inner = InnerException;
    Exception back = this;

    while (inner != null) {
        back = inner;
        inner = inner.InnerException;
    }

    return back;
}

显然,这是设计使然.来源中的评论没有说明为什么这样做.

So apparently it's like this by design. The comments in the source offer no explanation as to why they do this.

一些现在不见了的网站声称此评论来自Microsoft的一个家伙:

Some site that is now gone claims this comment came from a guy at Microsoft:

基于记录中的winform确认,我们的分析是 更正根本原因,并且此行为是有意的.原因是 防止用户看到过多的Windows.Forms内部机制. 这是因为Winform的默认错误对话框还利用Application.ThreadException来显示异常详细信息. .Net Winform 团队会整理其他异常信息,以使出现默认错误 对话框不会向最终用户显示所有详细信息.

Based on the winform comfirmation in the record, our analysis is correct of the root cause and this behavior is intended. The reason was to prevent the user from seeing too much of the Windows.Forms internal mechanisms. This is because the winform's default error dialog also leverages Application.ThreadException to show the exception details. .Net Winform team trims the other exceptions information so that the default error dialog will not display all the details to the end user.

此外,某些MSFT还建议更改此行为.但是,.Net Winform团队认为将异常更改为throw是一个突破 进行更改,因此WinForms将继续将最里面的异常发送到Application.ThreadException处理程序.

Also, some MSFTs have sugguested to change this behavior. However, .Net Winform team thinks that changing the exception to throw is a breaking change and for this reason WinForms will keep sending the innermost exception to the Application.ThreadException handler.

这篇关于Control.Invoke取消包装外部异常并传播内部异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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