我有一个wpf c#app。
我通常使用全局错误处理程序来捕获所有错误:
Task.Run(() =>
{
throw and error here
});
但是,如果启动task.run'代码'并且它会抛出错误,那么我发现错误没有被捕获:
Task.Run(() =>
{
try
{
throw an error here
}
catch (Exception ex)
{
do something with error
}
});
所以我必须把'Try-Catch'的东西用来捕捉它:
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.
};
〜这会破坏具有全局错误处理程序的对象 但是,如果我使用这种方法:
<% if Rails.env == "development" %>
<%= #include the local file here %>
<% else %>
<%= javascript_include_tag "http://www.google.com/jsapi", "chartkick" %>
<% end %>
...它将执行我的全局异常处理,但如果我想实时通知用户错误,那么它不会很好地执行,因为它是在一个单独的线程上。
什么是妥协?
答案 0 :(得分:2)
不幸的是,TaskScheduler.UnobservedTaskException
并不保证在被抛出的情况下实时触发。这意味着使用此处理程序进行用户通知可能会非常混乱,因为用户操作和错误通知不会同步发生。对于用户驱动的“意想不到的&#39;任务异常,您可以创建如下的帮助方法,并使用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驱动的代码中实现。