SynchronizationContext,什么时候流动,什么时候不流动?

问题描述 投票:0回答:1

我正在努力了解

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

如果我在线程池上执行东西,我是否被迫将同步上下文分配给当前正在执行我的工作的特定线程?

c# asynchronous task-parallel-library synchronizationcontext
1个回答
5
投票

在什么条件下当前同步上下文会与我的异步操作一起流动?

async
方法执行
await
时,默认情况下它将捕获当前上下文并使用它来恢复
async
方法。此上下文是
SynchronizationContext.Current
,除非它是
null
,在这种情况下它是
TaskScheduler.Current
。我在我的
async
介绍性博文
、关于 SynchronizationContext
MSDN 文章以及关于异步最佳实践的 MSDN 文章中描述了这种行为。

Task 和其他任务之间是否存在差异,例如:委托.BeginInvoke?

此行为是

async
await
所独有的。
Delegate.BeginInvoke
表示“在线程池线程上运行此委托”,因此它不会传播
SynchronizationContext
Task.Run
等更现代的方法也没有。

如果我在线程池上执行东西,我是否被迫将同步上下文分配给当前正在执行我的工作的特定线程?

一般来说,您不应该在不属于您的线程上安装同步上下文。如果您确实在线程池线程上放置了一个线程,则应在线程返回到线程池之前将其删除。更有可能的是,如果您正在安装同步上下文,您就不应该将线程返回(自定义同步上下文通常与该线程的“主循环”相关联)。

在上面的示例中,逻辑调用上下文流动,但同步上下文不流动。任何说明为什么会出现这种情况的指示都会很有趣。

其他上下文的记录甚至更少。 Stephen Toub 发表了关于该主题的权威文章。从本质上讲,一些数据(例如安全性)必须流动;大多数其他数据没有。

© www.soinside.com 2019 - 2024. All rights reserved.