C# SynchronizationContext,何时流动,何时不流动?
我正在努力学习C# SynchronizationContext,何时流动,何时不流动?,c#,asynchronous,task-parallel-library,synchronizationcontext,C#,Asynchronous,Task Parallel Library,Synchronizationcontext,我正在努力学习SynchronizationContext和朋友。 如果我在控制台应用程序开始时设置自定义同步上下文。 在什么条件下,当前同步上下文将与我的异步操作一起流动? 任务与其他任务(如委托.开始工作)之间是否存在差异 void Main() { SynchronizationContext.SetSynchronizationContext(new FooContext()); Action a = () => { var current
SynchronizationContext
和朋友。
如果我在控制台应用程序开始时设置自定义同步上下文。
在什么条件下,当前同步上下文将与我的异步操作一起流动?
任务
与其他任务(如委托.开始工作
)之间是否存在差异
void Main()
{
SynchronizationContext.SetSynchronizationContext(new FooContext());
Action a = () =>
{
var current = SynchronizationContext.Current;
//current is null here
};
a.BeginInvoke(null,null);
...sleep
如果我在线程池上执行东西,我是否必须为当前正在执行我的工作的特定线程分配一个同步上下文
在什么条件下,当前同步上下文将与我的异步操作一起流动
当async
方法执行wait
时,默认情况下它将捕获当前上下文并使用该上下文恢复async
方法。此上下文为SynchronizationContext.Current
,除非它为null
,在这种情况下,它是TaskScheduler.Current
。我在我的,我的,我的中描述了这种行为
任务与其他任务之间是否存在差异,例如,委派任务。开始任务
此行为是async
和wait
独有的Delegate.BeginInvoke
表示“在线程池线程上运行此委托”,因此它不会传播SynchronizationContext
。更现代的方法,如Task.Run
,也是如此
如果我在线程池上执行东西,我是否必须为当前正在执行我的工作的特定线程分配一个同步上下文
通常,您不应该在您不拥有的线程上安装同步上下文。如果确实在线程池线程上放置了一个线程,则应在该线程返回到线程池之前将其删除。更有可能的是,如果您正在安装一个同步上下文,您就不应该将线程退回(自定义同步上下文通常与该线程的“主循环”相关联)
在上面的示例中,逻辑调用上下文流动,而不是同步上下文。任何关于为什么会出现这种情况的指针都会很有趣
其他上下文的记录甚至更少。Stephen Toub拥有这一优势。本质上,某些数据(如安全性)必须流动;大多数其他数据都没有。看看这篇文章。但一个问题是,其他代码可以通过调用
.ConfigureAwait(false)
来选择停止同步上下文的“流动”。事实上,对于非UI库来说,这样做是最好的做法,因为它们不关心是否在同一线程上启动了wait
resume。这是一个不可能广泛的问题。唯一的方法是忘记委托的BeginInvoke()方法与SynchronizationContext有任何关系。“BeginInvoke”只是“异步运行代码”的通用名称。SynchronizationContext只与解决您在执行此操作时遇到的问题有关。也许可以回答一个解释,说明为什么它太宽泛?有很多文档让人相信同步上下文与异步操作之间的执行上下文一起流动。如上例所示,逻辑调用上下文流动,但同步上下文不流动。任何关于为什么会出现这种情况的指针都会很有趣。