Joe*_*ite 10 c# exception unhandled-exception
我有一个处理程序Application.ThreadException,但我发现异常并不总是正确传递给它.具体来说,如果我从BeginInvoke回调中抛出异常内部异常,我的ThreadException处理程序不会获得外部异常 - 它只获得内部异常.
示例代码:
public Form1()
{
InitializeComponent();
Application.ThreadException += (sender, e) =>
MessageBox.Show(e.Exception.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
var inner = new Exception("Inner");
var outer = new Exception("Outer", inner);
//throw outer;
BeginInvoke(new Action(() => { throw outer; }));
}
Run Code Online (Sandbox Code Playgroud)
如果我取消注释该throw outer;行并单击该按钮,则消息框将显示外部异常(以及其内部异常):
System.Exception:Outer ---> System.Exception:Inner
---内部异常堆栈跟踪的结束---
在C:\ svn\trunk\Code Base中的WindowsFormsApplication1.Form1.button1_Click(Object sender,EventArgs e) Source.NET\WindowsFormsApplication1\Form1.cs中:线55
在System.Windows.Forms.Control.OnClick(EventArgs的发送)
在System.Windows.Forms.Button.OnClick(EventArgs的发送)
在System.Windows.Forms.Button.OnMouseUp
System.Windows.Forms.BouttonBase.WndProc上的System.Windows.Forms.Control.WndProc(Message&m )处的System.Windows.Forms.Control.WmMouseUp(Message&m,MouseButtons按钮,Int32单击)
上的(MouseEventArgs mevent)
(Message&米)
在System.Windows.Forms.Button.WndProc(邮件&m)
在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(邮件&m)
在System.Windows.Forms.Control.ControlNativeWindow.WndProc(邮件&m)
在系统.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
但是如果throw outer;它在一个BeginInvoke调用中,就像在上面的代码中一样,那么ThreadException处理程序只获得内部异常.外部异常在ThreadException被调用之前被剥离,我得到的只是:
System.Exception:内部
(这里没有调用堆栈,因为inner从来没有被抛出.在一个更现实的例子中,我抓住了一个异常并将其包装成重新抛出,会有一个调用堆栈.)
如果我使用SynchronizationContext.Current.Post而不是BeginInvoke:同样的事情发生:外部异常被剥离,ThreadException处理程序只获取内部异常.
我尝试在外面包装更多的异常层,以防它只是剥离最外层的异常,但它没有帮助:显然某个地方有一个循环做一些事情while (e.InnerException != null) e = e.InnerException;.
我正在使用,BeginInvoke因为我有代码需要抛出一个未处理的异常才能立即处理ThreadException,但是这段代码位于catch调用堆栈上方的一个块内(具体来说,它在a的操作内部Task,Task并将捕获异常)并阻止它传播).我正在尝试使用BeginInvoke延迟throw直到下一次在消息循环中处理消息,当我不在其中时catch.我并不依赖于特定的解决方案BeginInvoke; 我只是想抛出一个未处理的异常.
ThreadException即使我在其他人的所有人中,我怎么能导致异常 - 包括其内部异常catch?
(ThreadException由于程序集依赖性,我无法直接调用我的-handler方法:处理程序被EXE的启动代码挂钩,而我当前的问题是在较低层的DLL中.)
一种方法是将内部异常引用放入自定义属性或字典中Data——即,将InnerException属性保留为空,并以其他方式携带引用。
当然,这需要建立某种可以在抛出代码和处理代码之间共享的约定。最好的方法可能是在两个代码段都引用的项目中定义具有自定义属性的自定义异常类。
示例代码(尽管它需要更多注释来解释为什么它正在做这些疯狂的事情):
public class ExceptionDecorator : Exception {
public ExceptionDecorator(Exception exception) : base(exception.Message) {
Exception = exception;
}
public Exception Exception { get; private set; }
}
// To throw an unhandled exception without losing its InnerException:
BeginInvoke(new Action(() => { throw new ExceptionDecorator(outer); }));
// In the ThreadException handler:
private void OnUnhandledException(object sender, ThreadExceptionEventArgs e) {
var exception = e.Exception;
if (exception is ExceptionDecorator)
exception = ((ExceptionDecorator) exception).Exception;
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1063 次 |
| 最近记录: |