我正在尝试了解SynchronizationContext
和朋友。
如果我在例如开始时设置自定义同步上下文控制台应用。
在什么条件下,当前的同步上下文会与我的异步操作一起流动?
Task
与其他人之间是否存在差异,例如Delegate.BeginInvoke
?
void Main()
{
SynchronizationContext.SetSynchronizationContext(new FooContext());
Action a = () =>
{
var current = SynchronizationContext.Current;
//current is null here
};
a.BeginInvoke(null,null);
...sleep
如果我在线程池上执行了东西,我是否被迫将同步上下文分配给当前正在执行我的工作的特定线程?
答案 0 :(得分:5)
当前同步上下文在什么条件下会与我的异步操作一起流动?
当async
方法执行await
时,默认情况下它会捕获当前上下文并使用它来恢复async
方法。除非是SynchronizationContext.Current
,否则此上下文为null
,在此情况下为TaskScheduler.Current
。我在async
intro blog post,我的MSDN article on SynchronizationContext
和我的MSDN article on async best practices中描述了这种行为。
任务与其他人之间是否存在差异,例如Delegate.BeginInvoke?
此行为对async
和await
是唯一的。 Delegate.BeginInvoke
表示"在线程池线程"上运行此委托,因此它不会传播SynchronizationContext
。也没有更多的现代方法,例如Task.Run
。
如果我在线程池上执行了东西,我是否被迫将同步上下文分配给当前正在执行我的工作的特定线程?
通常,您不应该在您不拥有的主题上安装同步上下文。如果您确实在线程池线程上放置了一个,则应在将线程返回到线程池之前将其删除。更有可能的是,如果您正在安装同步上下文,那么您就不应该回复该线程(自定义同步上下文通常与该主线的#34;主循环相关联)。
在上面的示例中,是逻辑调用上下文流,但不是同步上下文。任何指向这种情况的指针都会很有趣。
其他背景甚至没有记录。 Stephen Toub有definitive post on the subject。实质上,一些数据如安全必须流动;大多数其他数据没有。