如何获得一个使用SynchronizationContext的任务?以及SynchronizationContext是如

本文关键字:SynchronizationContext 任务 是如 以及 何获得 一个 | 更新日期: 2023-09-27 18:16:55

我还在学习整个Task-concept和TPL。根据我目前的理解,await使用SynchronizationContext函数(如果存在)来"某处"调度任务。另一方面,Task类中的函数不使用上下文,对吗?

因此,例如Task.Run(...)将始终在线程池的工作线程上调度操作,而完全忽略SynchronizationContext.Currentawait Foobar()将使用上下文在await之后执行生成的任务?

如果这是真的,我的问题是:我怎么能获得一个Task,它实际上运行一个动作,但使用SynchronizationContext.Current.Send/Post调度?

谁能推荐一个关于SynchronizationContext的好的介绍,特别是框架的其余部分何时以及如何使用它们?MSDN似乎对这个类很沉默。Google最热门的搜索结果(这里和这里)似乎只针对Windows窗体调度。Stephen Cleary写了一篇文章,很好地了解了已经存在的上下文以及它们是如何工作的,但我不了解它们实际使用的地点和时间。

如何获得一个使用SynchronizationContext的任务?以及SynchronizationContext是如

我如何获得一个任务,它实际运行一个操作,但使用SynchronizationContext.Current.Send/职位吗?

使用特殊任务调度程序:

Task.Factory.StartNew(
    () => {}, // this will use current synchronization context
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext());

谁能给我介绍一下SynchronizationContext

看看Stephen Cleary的文章It's All About the SynchronizationContext

在学习这一点时,重要的是要指出,TPL使用的Task 与async/await使用的Task 完全不同,尽管它们是相同的类型。例如,TPL通常使用父/子任务,但async/await不使用。

TPL使用任务调度器来执行它的任务。正如Dennis指出的,TaskScheduler.FromCurrentSynchronizationContext会给你一个任务调度器,它在当前SynchronizationContext上使用Post来执行它的任务。

async/await通常不使用任务调度程序。我在我的博客上有一篇async/await的介绍性文章,其中包括上下文信息,我也在我的MSDN文章中简要地提到了它(尽管很容易被忽视)。本质上,当async方法挂起在await时,默认情况下它将捕获当前的SynchronizationContext(除非它是null,在这种情况下它将捕获当前的TaskScheduler)。当async方法恢复时,它将继续在该上下文中执行。

Dennis指出了当前SynchronizationContext的TPL调度任务的方法,但在async/await的世界中,这种方法是不必要的。相反,您可以通过Task.Run显式地将任务调度到线程池:

async Task MyMethodAsync()
{
  // Whee, on a SynchronizationContext here!
  await Task.Run(() => { }); // Ooo, on the thread pool!
  // Back on the SynchronizationContext ...
  //  ... automagically!
}

我写SynchronizationContext文章正是因为MSDN文档太缺乏了。我的博客上有更多的信息,但所有重要的部分都在MSDN的文章中。许多类型直接使用AsyncOperation而不是SynchronizationContext;最好的文档在EAP文档中("线程和上下文"一节)。但是我还应该指出,由于async/await, EAP实际上已经过时了,所以我不会使用AsyncOperation(或SynchronizationContext)编写代码-除非我实际上是在编写我自己的 SynchronizationContext