我的应用程序有多个 Dispatcher
(又称GUI线程,消息泵),以确保GUI的某个缓慢、无响应的部分不会对整个应用程序产生太大影响。我还经常使用 Task
。
目前,我有一些代码条件性地在 TaskScheduler
或 Dispatcher
上运行 Action
,然后直接返回一个 Task
或通过手动创建一个 TaskCompletionSource
来返回一个 Task
。然而,这种拆分式设计使得处理取消、异常等问题变得比我想象的要复杂得多。我希望在任何地方都使用 Task
,而不是 DispatcherOperation
。为此,我需要在调度程序上安排任务——但如何实现呢?
如何获得特定 Dispatcher
的 TaskScheduler
?
编辑:在下面的讨论之后,我决定采用以下实现方式:
public static Task<TaskScheduler> GetScheduler(Dispatcher d) {
var schedulerResult = new TaskCompletionSource<TaskScheduler>();
d.BeginInvoke(() =>
schedulerResult.SetResult(
TaskScheduler.FromCurrentSynchronizationContext()));
return schedulerResult.Task;
}
Aborted
事件处理得很好!唯一剩下的缺点是任务计划程序是异步创建的;也就是说,您必须等待调度程序运行调用后才能安排任务(这不是一个主要问题,因为您可以使用ContinueWith
,但有点不方便)。 - Eamon Nerbonneawait
在这里实际上做的是相同的事情,即导致在Dispatcher运行后异步执行的Task
。具体来说,这意味着当包含方法的执行完成时,任务调度程序可能尚不可用(即在.NET 4.5中问题仍然存在)。这不是关键问题;无论如何,只要创建调度程序的唯一方式是在同步上下文本身上(这是一个奇怪的API限制,但它就是这样...), 就不能解决它。 - Eamon Nerbonne