C# 如何获取使用SynchronizationContext的任务?SynchronizationContext是如何使用的?

C# 如何获取使用SynchronizationContext的任务?SynchronizationContext是如何使用的?,c#,async-await,synchronizationcontext,C#,Async Await,Synchronizationcontext,我仍在学习整个任务概念和第三方物流。根据我目前的理解,wait使用SynchronizationContext函数(如果存在)将任务分派到“某处”。另一方面,任务类中的函数不使用上下文,对吗 因此,例如Task.Run(…)将始终在线程池的工作线程上调度操作,并完全忽略SynchronizationContext.Currentawait Foobar()将在await之后使用上下文执行生成的任务 如果这是真的,那么我的问题是:如何获得一个任务,该任务实际运行一个操作,但使用Synchroniz

我仍在学习整个任务概念和第三方物流。根据我目前的理解,
wait
使用SynchronizationContext函数(如果存在)将任务分派到“某处”。另一方面,
任务
类中的函数不使用上下文,对吗

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

如果这是真的,那么我的问题是:如何获得一个
任务
,该任务实际运行一个操作,但使用
SynchronizationContext.Current.Send/Post
进行调度


还有谁能推荐一个好的介绍
同步上下文
,特别是框架的其他部分何时以及如何使用它们?老师对这门课似乎很安静。谷歌的热门搜索(和)似乎只针对Windows窗体。斯蒂芬·克利里(Stephen Cleary)写道,很高兴了解什么样的上下文已经存在以及它们是如何工作的,但我对它们实际在哪里和何时被使用缺乏了解

如何获得一个任务,该任务实际运行一个操作,但使用 SynchronizationContext.Current.Send/Post

使用特殊任务计划程序:

Task.Factory.StartNew(
    () => {}, // this will use current synchronization context
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext());
还有谁能推荐一个关于SynchronizationContext的好介绍吗


请看Stephen Cleary的文章。

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


TPL使用任务调度器执行其任务。正如丹尼斯指出的,
TaskScheduler.FromCurrentSynchronizationContext
将为您提供一个任务调度器,它使用当前
SynchronizationContext
上的
Post
来执行其任务


async
/
await
通常不使用任务调度器。我在我的博客上有一篇介绍性文章,其中包含了上下文信息,我在我的博客中也简要地提到了这一点(尽管这很容易被忽视)。本质上,当
异步
方法挂起在
等待
时,默认情况下它将捕获当前的
同步上下文
(除非它为
,在这种情况下它将捕获当前的
任务调度器
)。当
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
,所以我不会使用
AsyncOperation
(或
SynchronizationContext
)编写代码,除非我真的在编写自己的
SynchronizationContext

啊,很好。谢谢
Task.Run
Task.Factory.StartNew
之间有什么区别吗?(我的意思是..除了“
Task.Factory.StartNew
接受一些
Task.Run
不接受的参数”之外,还有什么区别吗?)看看这篇文章。谢谢你的链接。我已经读过那篇文章,并在我的问题中把它联系了起来——这对于理解什么样的上下文存在以及为什么要首先引入它们非常有帮助。有没有其他好的资料来源,可能会详细介绍什么时候哪个类使用上下文?还是我接触TPL的方式有误,我应该读到“为什么我真的不应该关心这个”?:D.还有其他一些:
Task.Run
理解并自动展开
async
委托,
Task.Run
始终使用线程池调度程序(而
Task.Factory.StartNew
将使用当前任务调度程序),和
Task.Run
默认情况下将传递
denychildatach
选项。如果存在
TaskCreationOptions,则为None
而不是
TaskContinuationOptions.None
?SynchronizationContext(除非它为null,在这种情况下它将捕获当前的TaskScheduler)。有趣的。。。事实上,当阅读TaskScheduler的时,我开始认为TaskScheduler——而不是SynchronizationContext——是解决我的原始问题所需要的(这里没有描述)。您对TaskScheduler和SynchronizationContext有很好的参考资料吗?它们之间的区别是什么?(从MSDN来看,两者似乎都负责将任务发送到线程上,对吗?
SynchronizationContext
是使用.NET 2.0开发的,用于调度委托(同步或异步)
TaskScheduler
是在.NET 4.0中引入的,用于(异步)调度任务。