簡體   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