如何获取使用SynchronizationContext的任务?那么SynchronizationContext是如何使用的呢?

Imi*_*Imi 25 c# synchronizationcontext async-await

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

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

如果这是真的,我的问题是:我怎样才能获得a Task,实际运行一个动作但是被派遣使用SynchronizationContext.Current.Send/Post

任何人都可以推荐一个很好的介绍SynchronizationContext,特别是在框架的其余部分使用它们的时间和方式?在MSDN似乎很沉默的类.顶级Google点击(此处此处)似乎仅适用于Windows Forms调度.Stephen Cleary撰写了一篇文章,很好地了解了已经存在的背景以及它们是如何工作的,但我不了解实际使用的地点和时间.

Den*_*nis 40

如何获取实际运行操作但使用SynchronizationContext.Current.Send/Post调度的任务?

使用特殊任务调度程序:

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

任何人都可以推荐一个很好的SynchronizationContext介绍

请看Stephen Cleary 撰写的关于SynchronizationContext的文章.

  • 有*其他一些[Task.Run`和`Task.Factory.StartNew`之间的差异](http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) :`Task.Run`理解并自动解包`async`委托,`Task.Run`总是使用线程池调度程序(而`Task.Factory.StartNew`将使用当前任务调度程序),`Task.Run`将默认情况下传递`DenyChildAttach`选项. (7认同)

Ste*_*ary 26

在您了解这一点时,重要的是要指出Task TPL Task 使用的与async/await使用的完全不同,即使它们是相同的类型.例如,TPL通常使用父/子任务,但是async/ await不是.

TPL使用任务调度程序来执行其任务.正如Dennis指出的那样,TaskScheduler.FromCurrentSynchronizationContext将为您提供一个任务调度程序,它使用Post当前SynchronizationContext执行其任务的方式.

async/ await通常不使用任务调度程序.我在我的博客上有一个介绍async/ await帖子,其中包含上下文信息,我在MSDN文章中也简要提到过它(虽然很容易忽略).本质上,当一个async方法挂起时await,默认情况下它将捕获当前的电流SynchronizationContext(除非是null,在这种情况下它将捕获当前电流TaskScheduler).当async方法恢复时,它将继续在该上下文中执行.

Dennis指出了将任务安排到当前的TPL方式SynchronizationContext,但在async/ awaitworld中,这种方法不是必需的.相反,您可以通过Task.Run以下方式将任务显式地安排到线程池:

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

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

  • `SynchronizationContext` 是用 .NET 2.0 开发的,用于调度委托(同步或异步)。`TaskScheduler` 是在 .NET 4.0 中引入的,用于调度任务(异步)。 (2认同)