从GUI线程抛出的AggregateException为什么会“解开"?在应用程序异常处理程序中? [英] Why does AggregateException thrown from GUI thread get "unwrapped" in app exception handler?

查看:129
本文介绍了从GUI线程抛出的AggregateException为什么会“解开"?在应用程序异常处理程序中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WinForm异步GUI应用程序,其中在program.cs中设置了一些全局"异常处理.我也有一个GUI线程正在执行"await Task.WhenAll()"并捕获其异常并抛出awaited Task.Exception属性,以便AggregateException一直到达program.cs中的异常处理程序(我想遍历内部异常并将它们记录下来.

I have a WinForm async GUI app in which I've set up some "global" exception handling in program.cs. I also have a GUI thread that's doing an "await Task.WhenAll()" and catching its exception and throwing the awaited Task.Exception property, so that the AggregateException gets all the way to the exception handler in program.cs (I want to iterate over the inner exceptions and log them).

我可以看到,从TryAll()的try/catch中抛出的异常确实引发了AggreateException,但是当我在program.cs中调试处理程序时,它不再是AggregateException-它只是第一个异常的AggregateException.我不知道是什么代码在为我做解包"?

I can see that the exception being thrown out of my try/catch of the WhenAll() is indeed throwing an AggreateException, but when I debug the handler in program.cs, it's not an AggregateException anymore - it's just the first Exception of the AggregateException. I can't figure out what code is doing this "unwrapping" for me?

Program.cs:

Program.cs:

static void Main() {
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    ...
    }

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
            if (e.Exception is AggregateException) {
                // expect to log the contents of (e.Exception as AggregateException).Flatten().InnerExceptions, but exception coming 
                // in is not AggregateException but instead is
                // ApplicationException("message 1")
                }
            else {
                // handling for non aggregate exceptions
                }

在Form1.cs

private async void button1_Click(object sender, EventArgs e) {

            Task overall = Task.WhenAll(
                Task.Run(()=>  { throw new ApplicationException("message 1"); }),
                Task.Run(() => { throw new ApplicationException("message 2"); })
                );

            try {
                await overall;
                }
            catch {
                throw overall.Exception; // this is AggregateException
                }
            }
        }

推荐答案

不仅是 AggregateException -WinForms总是 仅发送 GetBaseException()给处理程序.也就是说,只有任何 InnerException 链的最内层异常.

It's not just AggregateException - WinForms will always only send GetBaseException() to the handler. That is, only the innermost exception of any InnerException chain.

显然,这是长期存在的WinForms错误,目前可能是永久性的.

Apparently this is a longstanding WinForms bug, probably permanent at this point.

您必须使用自己的类型来解决它:

You'll have to work around it with your own type:

public class ExceptionWrapper : Exception
{
    public new Exception InnerException { get; set; }
}

throw new ExceptionWrapper { InnerException = overall.Exception };

这篇关于从GUI线程抛出的AggregateException为什么会“解开"?在应用程序异常处理程序中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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