繁体   English   中英

为什么我的Task.ContinueWith不在.NET 4.5中执行?

[英]Why doesn't my Task.ContinueWith execute in .NET 4.5?

请考虑以下代码

Task<T>.Factory.StartNew(() => 
    {
      // block #1: load some data from local file cache
    }
  )
  .ContinueWith(task => 
    {
      // block #2: handle success or failure of load-from-cache operation and surface to application
    }, 
    cancellationToken,
    TaskContinuationOptions.NotOnCanceled,
    TaskScheduler.FromCurrentSynchronizationContext()
  )
  .ContinueWith(task => 
    {
      // block #3: load data from remote data source
    },
    TaskContinuationOptions.NotOnCanceled
  );

在.NET 4.0中,此代码按预期执行:第一个块在后台线程中运行,然后第二个块运行,最后第三个块运行。

但是,在.NET 4.5中,无论第一个块发生了什么(成功,故障或取消),第二个块都不会运行。 并且第三个块也不运行,等待非启动的第二个块。

申请背景

此代码位于WPF应用程序中。 它在应用程序初始化期间运行,加载应用程序启动所需的一些数据。 在主线程(我称之为异步代码)中,我正在等待从代码块#3填充结果,然后再继续。 如果远程数据调用超时,则将继续初始化来自块#1(缓存)的数据。

我尝试过的事情

  1. 将TaskScheduler.FromCurrentSynchronizationContext()添加到StartNew调用。 这导致Star​​tNew lambda中的代码永远不会执行(即使它确实如此,我也不希望它在主线程上运行)。
  2. 从ContinueWith中删除TaskScheduler.FromCurrentSynchronizationContext()(并保留cancellationToken或TaskContinuationOptions,但不要同时保留两者,因为没有重载只支持这两个参数)。 这似乎工作(代码执行),但我担心副作用,因为我不知道为什么它的工作原理。

在这两个版本的.Net中,我们遇到了ContinueWith和TaskScheduler属性Current和Default的设计问题

在.Net 4.0中,TaskScheduler的Current和Default都具有相同的值,即ThreadPoolTask​​Scheduler ,它是ThreadPool的上下文调度程序,它不是更新UI的那个,即SynchronizationContextTaskScheduler ,这就是你的代码在.Net 4.0中正常运行的原因。

在.Net 4.5中,事情发生了变化。 所以,当你说TaskScheduler.Current和TaskScheduler.Default然后你会得到两个不同的调度程序(在你的情况下WPF时)

Current is = SynchronizationContextTaskScheduler

默认是= ThreadPoolTask​​Scheduler

现在回到你的问题,当你使用ContinueWith选项时,它具有调度程序的硬编码值作为TaskScheduler.Current。 具体来说,在WPF和Asp.net中,SynchronizationContextTaskScheduler意味着它是UI线程同步上下文,一旦被阻止,在执行当前执行线程并在UI线程上下文中运行之前,其他任何内容都不会执行。

建议(.Net 4.5): 尝试在ContiueWith中传递TaskScheduler.Default(NON UI Scheduler)或避免使用ContinueWith,而是以排队方式加入任务。

我希望这能清楚地说明行为正在发生变化的原因。 有关更多详细信息,请参阅此讨论: 为什么TaskScheduler.Current是默认的TaskScheduler?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM