【问题标题】:TPL on Windows XPWindows XP 上的 TPL
【发布时间】:2013-10-18 18:17:38
【问题描述】:

我们有一个 WPF 应用程序,其中:

private void SomeHandler(object sender, RoutedEventArgs e)
{
  Task.Factory.StartNew(LoadItems).ContinueWith(t =>
  {
    //cache items to, for instance, db
  }, TaskContinuationOptions.NotOnFaulted);
}

private void LoadItems()
{
//sometimes it throws an exception
//this is expected
throw new FormatException("blablabla");
}

所以,一般来说,当数据存在时,我们使用这个处理程序来尝试缓存数据。 如果它不存在,那么我们会得到一个 Formatexception。我们不关心结果,只关心“一劳永逸”的策略。

我最近收到了来自客户端的两个日志文件,其中我看到 FormatException 已传播到 CurrentDomain_UnhandledException 处理程序。所有客户端都在带有 .Net 4.0 的 Windows XP 上。

所以问题是为什么会这样?是否符合设计?

【问题讨论】:

    标签: c# wpf task-parallel-library


    【解决方案1】:

    这是 .Net 4.0 上的预期行为。如果存在带有异常的 Task 并且从未观察到该异常,则在完成 Task 时重新抛出该异常。

    如果您安装了 .Net 4.5 并且想要获得此行为(例如用于测试),add <ThrowUnobservedTaskExceptions> to app.config

    如果您想确保不会重新抛出未观察到的 Task 异常,即使在 .Net 4.0 上,您也可以使用 TaskScheduler.UnobservedTaskException

    TaskScheduler.UnobservedTaskException += (o, args) => args.SetObserved();
    

    但我认为这里最好的选择是明确地观察异常。您可以通过删除 NotOnFaulted 选项并改为检查 Exception 属性来做到这一点:

    Task.Factory.StartNew(LoadItems).ContinueWith(t =>
    {
      if (t.Exception == null)
      {
        //cache items to, for instance, db
      }
    });
    

    【讨论】:

    • 请记住,如果继续任务也引发了从未观察到的异常,那么您将直接回到同一条船上:)
    • 这是一个有趣的突破性变化...感谢您的解释
    • 一个更有趣的观察,因为在终结器中抛出异常,即使安装了 UnhandledException 处理程序,应用程序也会终止。这是我在应用程序日志中看到的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多