.net - 如何获取调度程序的 TaskScheduler?

标签 .net wpf multithreading task dispatcher

我有一个具有多个Dispatcher(又名 GUI 线程、又名消息泵)的应用程序,以确保 GUI 的缓慢且无响应的部分运行,而不会严重影响应用程序的其余部分。我也经常使用 Task

目前,我的代码可以在 TaskSchedulerDispatcher 上有条件地运行 Action,然后返回 Task 直接或使用 TaskCompletionSource 手动创建一个。然而,这种人格 split 的设计使得处理取消、异常(exception)等事情比我想象的要复杂得多。我想在任何地方使用 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;
}

最佳答案

第 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;
}

第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 (() => { ... });

新语法:

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

关于.net - 如何获取调度程序的 TaskScheduler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6368885/

相关文章:

.net - 使用哪个 Azure Blob 客户端库? Microsoft.Azure.Storage.Common 或 WindowsAzure.Storage?

c# - 为什么 LINQ .Where(predicate).First() 比 .First(predicate) 快?

c++ - 在 C++ 中使用 pthread 时出现编译错误

c# - WPF DataGrid 插入和更新绑定(bind)

java - 线程和同步问题

Python 使用键 : possible to parallelize? 排序

c# - 在 .NET Framework 3.5 或 4.0 上运行的可执行文件

.net - 是否可以创建嵌套命名空间? (可以这么说)

c# - 处理 "The operation completed successfully"错误

c# - WPF 从用户控件调用父方法