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());
任何人都可以推荐一个很好的SynchronizationContext介绍
请看Stephen Cleary 撰写的关于SynchronizationContext的文章.
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!
}
我SynchronizationContext正好写了我的文章,因为MSDN文档非常缺乏.我在我的博客上有更多的信息,但所有重要的部分都在MSDN文章中.许多类型使用AsyncOperation而不是SynchronizationContext直接使用; 最好的文档隐藏在EAP文档("线程和上下文"部分)下.但我还应该指出,由于async/ await,EAP实际上是过时的,因此我不会使用AsyncOperation(或SynchronizationContext)编写代码- 除非我实际上是在编写自己的代码 SynchronizationContext.