我有一个WPF C#应用程序。
我通常使用全局错误处理程序来捕获所有错误:
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
try
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => Xceed.Wpf.Toolkit.MessageBox.Show(e.Exception.ToString(), "Error",
MessageBoxButton.OK, MessageBoxImage.Error)));
e.Handled = true;
InformedWorkerDataService.Common.Shared.RecordMessage(e.Exception.ToString(), true);
}
finally { }
}
但是,如果从task.run'代码的位'开始并引发错误,那么我观察到该错误未被捕获:
Task.Run(() =>
{
throw and error here
});
所以我必须放入一个“Try-Catch”东西来捕获它:
Task.Run(() =>
{
try
{
throw an error here
}
catch (Exception ex)
{
do something with error
}
});
〜击败了具有全局错误处理程序的对象
但是,如果我使用这种方法:
TaskScheduler.UnobservedTaskException += (s, e) => {
e.Exception //The Exception that went unobserved.
e.SetObserved(); //Marks the Exception as "observed," thus preventing it from triggering exception escalation policy which, by default, terminates the process.
};
...它将执行我的全局异常处理,但是如果我想实时将错误通知用户,则效果不佳,因为它位于单独的线程上。
有什么好的折衷办法?
最佳答案
不幸的是,除了抛出异常外,TaskScheduler.UnobservedTaskException
不能保证实时触发。这意味着使用此处理程序进行用户通知可能会造成困惑,因为用户操作和错误通知将不会同步发生。对于用户驱动的“意外”任务异常的处理,您可以创建以下帮助方法,并使用TaskEx.Run
而不是Task.Run
:
public static class TaskEx
{
public static Task Run(Action function)
{
return Task.Run(() =>
{
try
{
function();
}
catch (Exception ex)
{
TraceEx.TraceException(ex);
//Dispatch your MessageBox etc.
}
});
}
}
显然,这不像添加全局处理程序(为了跟踪目的仍应这样做)那样简单,而是足够简单以在UI驱动的代码中实现。
关于wpf - Task.Run中的全局错误处理可实时通知用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34735922/