同步上下文,它何时流动,何时不流动
本文关键字:何时 不流动 上下文 同步 何时流 | 更新日期: 2023-09-27 18:32:33
我正在尝试了解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
如果我在线程池上执行内容,是否强制将同步上下文分配给当前正在执行我工作的特定线程?
在什么情况下,当前同步上下文将与我的异步操作一起流动?
当async
方法执行await
时,默认情况下它将捕获当前上下文并使用它来恢复async
方法。除非null
,否则这个上下文是SynchronizationContext.Current
的,在这种情况下它是TaskScheduler.Current
的。我在 async
介绍博客文章、有关 SynchronizationContext
的 MSDN 文章和有关异步最佳做法的 MSDN 文章中描述了此行为。
Task和其他任务之间是否有区别,例如Delegate.BeginInvoke?
此行为对于async
和await
是唯一的。 Delegate.BeginInvoke
表示"在线程池线程上运行此委托",因此它不会传播SynchronizationContext
。更现代的方法(如 Task.Run
.
如果我在线程池上执行内容,是否强制将同步上下文分配给当前正在执行我工作的特定线程?
通常,不应在不属于您的线程上安装同步上下文。如果确实在线程池线程上放置了一个线程,则应在线程返回到线程池之前将其删除。更有可能的是,如果您正在安装同步上下文,则永远不应该返回线程(自定义同步上下文通常与该线程的"主循环"相关联(。
在上面的示例中,逻辑调用上下文流动,但不流动同步上下文。 任何说明为什么会这样会很有趣的指针都会很有趣。
其他上下文的记录更少。斯蒂芬·图布(Stephen Toub(在这个问题上有权威的帖子。从本质上讲,某些数据(例如安全性(必须流动;大多数其他数据没有。