Dot-Net

如何獲得 Dispatcher 的 TaskScheduler?

  • June 16, 2011

我有一個具有多個Dispatchers 的應用程序(又名 GUI 執行緒,又名消息泵),以確保 GUI 的緩慢、無響應部分執行而不會嚴重影響應用程序的其餘部分。我也用Task的很多。

目前,我有有條件Action地在 aTaskScheduler或 a上執行 a 的程式碼,Dispatcher然後Task直接返回 a 或使用TaskCompletionSource. 然而,這種人格分裂的設計使得處理取消、異常等都比我想的要復雜得多。我想在任何地方都使用Tasks 並且DispatcherOperation無處使用 s。為此,我需要在調度員上安排任務 - 但如何?

我怎樣才能得到TaskScheduler任何給定的Dispatcher

**編輯:**經過下面的討論,我確定了以下實現:

public static Task<TaskScheduler> GetScheduler(Dispatcher d) {
   var schedulerResult = new TaskCompletionSource<TaskScheduler>();
   d.BeginInvoke(() => 
       schedulerResult.SetResult(
           TaskScheduler.FromCurrentSynchronizationContext()));
   return schedulerResult.Task;
}

第 1 步:創建擴展方法:

public static Task<TaskScheduler> ToTaskSchedulerAsync (
   this Dispatcher dispatcher,
   DispatcherPriority priority = DispatcherPriority.Normal) {

   var taskCompletionSource = new TaskCompletionSource<TaskScheduler> ();
   var invocation = dispatcher.BeginInvoke (new Action (() =>
       taskCompletionSource.SetResult (
           TaskScheduler.FromCurrentSynchronizationContext ())), priority);

   invocation.Aborted += (s, e) =>
       taskCompletionSource.SetCanceled ();

   return taskCompletionSource.Task;
}

第二步:使用擴展方法:

舊語法

var taskSchedulerAsync = Dispatcher.CurrentDispatcher.ToTaskSchedulerAsync ();
var taskFactoryAsync = taskSchedulerAsync.ContinueWith<TaskFactory> (_ =>
   new TaskFactory (taskSchedulerAsync.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
// this is the only blocking statement, not needed once we have await
var taskFactory = taskFactoryAsync.Result;
var task = taskFactory.StartNew (() => { ... });

新語法

var taskScheduler = await Dispatcher.CurrentDispatcher.ToTaskSchedulerAsync ();
var taskFactory = new TaskFactory (taskScheduler);
var task = taskFactory.StartNew (() => { ... });

引用自:https://stackoverflow.com/questions/6368885