jpb*_*chi 14 .net wpf exception-handling exception invoke
这是我的假设例子.我有一个非常简单的WPF窗口,带有一个Button.Button.Click事件有一个像这样的处理程序.
Action doit = () =>
{
Action error = () => { throw new InvalidOperationException("test"); };
try {
this.Dispatcher.Invoke(error, DispatcherPriority.Normal);
} catch (Exception ex) {
System.Diagnostics.Trace.WriteLine(ex);
throw;
}
};
doit.BeginInvoke(null, null);
Run Code Online (Sandbox Code Playgroud)
我希望通过Trace.WriteLine调用捕获并记下异常.相反,没有捕获异常并且应用程序中断.
有人知道可能的解释吗?为了捕获被调用的委托抛出的异常,您建议使用哪种解决方法Dispatcher.Invoke?
更新1:我throw在异常处理代码中添加了一个.我不想实际忽略该异常.我的问题的重点是正确处理它.问题是永远不会执行异常处理代码.
请记住,这是一个假设的例子.我的真实代码看起来不像那样.另外,假设我无法更改要调用的方法中的代码.
更新2:考虑这个类似的例子.我有一个Windows窗体窗口而不是WPF窗口.它有一个按钮,几乎完全相同的处理程序.唯一的区别在于调用代码.它是这样的.
this.Invoke(error);
Run Code Online (Sandbox Code Playgroud)
在Windows窗体中,执行异常处理代码.为什么不同?
更新:要观察另一个线程中的异常,您要使用a Task,将其Dispatcher排入线程(使用TaskScheduler.FromCurrentSynchronizationContext),并等待它,如下所示:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Action doit = () =>
{
var error = Task.Factory.StartNew(
() => { throw new InvalidOperationException("test"); },
CancellationToken.None,
TaskCreationOptions.None,
ui);
try {
error.Wait();
} catch (Exception ex) {
System.Diagnostics.Trace.WriteLine(ex);
}
};
doit.BeginInvoke(null, null);
Run Code Online (Sandbox Code Playgroud)
(再次)更新:既然你的目标是可重用的组件,我建议迁移到Task基于接口或其他东西依据SynchronizationContext,如基于事件的异步模式,而不是在基础部件Dispatcher或ISynchronizeInvoke.
Dispatcher基于组件的组件仅适用于WPF/Silverlight; ISynchronizeInvoke基于组件的组件仅适用于Windows窗体.SynchronizationContext基于组件的组件可以透明地与WPF或Windows Forms一起使用,并且(有更多工作)ASP.NET,控制台应用程序,Windows服务等.
基于事件的异步模式是编写SynchronizationContext基于组件的旧方法; 它仍然适用于.NET 3.5时代代码.但是,如果您使用的是.NET 4,则任务并行库更加灵活,干净且功能强大.下面的TaskScheduler.FromCurrentSynchronizationContext用法SynchronizationContext,是编写需要这种同步的可重用组件的新方法.
| 归档时间: |
|
| 查看次数: |
5109 次 |
| 最近记录: |