Eam*_*nne 17 .net wpf multithreading task dispatcher
我有一个带有多个应用程序Dispatcher
(也就是GUI线程,也就是消息泵)的应用程序,以确保GUI的缓慢,无响应部分运行而不会过多地影响应用程序的其余部分.我也经常使用Task
.
目前我已经有条件运行Action
a TaskScheduler
或a的代码Dispatcher
然后Task
直接返回或通过手动创建一个使用TaskCompletionSource
.然而,这种分裂的个性设计使得处理取消,异常等等都比我想要的复杂得多.我想在任何地方使用Task
s而且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 次 |
最近记录: |