Task.Run中的全局错误处理用于实时用户ntofication

时间:2016-01-12 05:00:22

标签: wpf error-handling task

我有一个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 %>

...它将执行我的全局异常处理,但如果我想实时通知用户错误,那么它不会很好地执行,因为它是在一个单独的线程上。

什么是妥协?

1 个答案:

答案 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驱动的代码中实现。