Eam*_*nne 17 .net wpf multithreading task dispatcher
我有一个带有多个应用程序Dispatcher(也就是GUI线程,也就是消息泵)的应用程序,以确保GUI的缓慢,无响应部分运行而不会过多地影响应用程序的其余部分.我也经常使用Task.
目前我已经有条件运行Actiona TaskScheduler或a的代码Dispatcher然后Task直接返回或通过手动创建一个使用TaskCompletionSource.然而,这种分裂的个性设计使得处理取消,异常等等都比我想要的复杂得多.我想在任何地方使用Tasks而且DispatcherOperation无处可去.要做到这一点,我需要在调度员上安排任务 - 但是如何?
如何获得TaskScheduler任何给定的Dispatcher?
编辑:在下面的讨论之后,我决定采用以下实现:
public static Task<TaskScheduler> GetScheduler(Dispatcher d) {
var schedulerResult = new TaskCompletionSource<TaskScheduler>();
d.BeginInvoke(() =>
schedulerResult.SetResult(
TaskScheduler.FromCurrentSynchronizationContext()));
return schedulerResult.Task;
}
Run Code Online (Sandbox Code Playgroud)
Geo*_*kos 14
第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;
}
Run Code Online (Sandbox Code Playgroud)
第2步:使用扩展方法:
旧语法:
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 (() => { ... });
Run Code Online (Sandbox Code Playgroud)
新语法:
var taskScheduler = await Dispatcher.CurrentDispatcher.ToTaskSchedulerAsync ();
var taskFactory = new TaskFactory (taskScheduler);
var task = taskFactory.StartNew (() => { ... });
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有内置的方法来做到这一点.有没有内置专门用于包裹一类Dispatcher的TaskScheduler-我们有最密切的是一个包装了一个SynchronizationContext.为建设唯一的公共API TaskScheduler从SynchronizationContext是一个保罗·米哈利克提到:TaskScheduler.FromCurrentSynchronizationContext-和你观察,仅如果在培训相关的同步环境是已经(即,有关调度的线程)的作品.
所以你有三个选择:
TaskScheduler.FromCurrentSynchronizationContext按预期使用.Dispatcher.BeginInvoke在调度程序线程上运行一些代码,并在该代码中调用TaskScheduler.FromCurrentSynchronizationContext.(换句话说,如果你不能自然地安排1.强迫它发生.)| 归档时间: |
|
| 查看次数: |
6693 次 |
| 最近记录: |