Invoke取消包装外部异常并传播内部异常

Invoke取消包装外部异常并传播内部异常

本文介绍了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:

此外,某些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取消包装外部异常并传播内部异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 16:29