深入理解 SynchronizationContext

SynchronizationContext(后续以SC简称) 是什么?

1.1 概念

​ 在 .NET 框架的多线程程序中,往往很多时间需要将一个线程工作单元或上下文,传递给另一个线程。我们都知道的是 Windows 上的程序是以 消息循环为中心的,这个如何理解呢?

每一个 window 窗体都有一个与之关联的 Window Procedure,这个是一个用来处理所有消息发送或发送到类的给所有消息的函数。窗体的所有UI显示和显示都取决于 Window Procedure 对这些消息的响应。

SynchronizationContext 主要提供了一下三方面的功能:

​ 1) 提供了一种把工作单元 添加到 上下文的队列中的方法。

​ 2) 每一个线程 都有 一个 “current” 的 上下文。

​ 3) 它保存着未完成异步操作数的计数,这个数量 随着 当前的 SC 被捕获,或被夺取时增加,当捕获的 SC 用于将完成通知排队发送到该上下文时,则减少。

// 重要的 SynchronizationContext APIClass
{
// Dispather work to the context.
void Post(); // Asynchronously
void send(); // Synchronously // Keep track of the number of asynchronous operations.
void OperationStarted();
void OperationCompleted(); // Each thread has a current context.
// If "Current" is null, then the thread's current context is
// "new SynchronizationContext()", by convention.
static SynchronizationContext Current{get;}
static void SetSynchronizationContext(SynchronizationContext);
}

1.2 SynchronizationContext 的实现

1)WindowsFormsSynchronizationContext (System.Windows.Forms.dll)

​ 1,Use ISynchronizeInvoke on UI Control,用来将委托传递 给 win32 message loop

​ 2,每一个 UI 线程 都会创建一个 WindowsFormsSynchronizationContext

​ 3,WindowsFormsSynchronizationContext 的上下文是一个 单一的UI 线程

2)DispatcherSynchronizationContext(WindowsBase.dll: System.Windows.Threading)

​ 1,以 “Normal” 优先级的委托 传递给 UI 线程。

​ 2,所有排队到 DispatcherSynchronizationContext 的委托都是由 特定的UI线程 按照他们排队的顺序 依次执行,一次执行一个。

​ 3,DispatcherSynchronizationContext 的上下文是一个 单一的 UI 线程

3)Default(ThreadPool) SynchronizationContext(mscorlib.dll: System.Threading)

​ 1,默认的 SynchronizationContext 是一个默认构造函数的 SynchronizationContext 对象,按照惯例,如果一个线程 当前的 SynchronizationContext 是 null,那么它会 隐式的 含有一个 默认的 SynchronizationContext

​ 2,默认 SynchronizationContext 将它的异步委托 添加到 线程池 队列,但是 在调用的线程上执行它的同步委托。因此,它的上下文 涵盖了 所有的线程池的线程 以及 调用它的线程。上下文 “借用” 调用它的线程,然后把它们带入到上下文中 直到委托结束。从某种意义上来说,默认上下文可能包含当前进程中的任何线程。

​ 3,默认 SynchronizationContext 是应用在 线程池中的线程的除非是被 ASP.NET 托管的代码,默认的 SynchronizationContext 也隐式应用于显式的子线程中除非子线程设置了自己的 SynchronizationContext。因此,UI 的应用一般都有两个 SynchronizationContext, UI 的 SynchronizationContext cover UI thread, default SynchronizationContext cover ThreadPool thread。

图1 是一个典型比如 WPF 程序,调用 Dispatcher.InvokeDispatcher.BeginInvoke 时Context 转换的一个图。

private void On_Time_Elapsed(object sender, EventArgs e)
{
Dispatcher.Invoke(()=>{
_displayTextBlock.Text = "Show Here.";
});
}

图1

图2 是 WPF 程序中,Dispatcher.Invoke 中又新开了线程池的线程执行的例子。

private void On_Time_Elapsed(object sender, EventArgs e){
Dispatcher.Invoke(()=>{
Task.Run(()=>{
// Do Something here.
}); _displayTextBlock.Text = "1111";
});
}

图2

各个不同实现的 SynchronizationContext 的区别

Specific Thread Used to Execute Delegates Exclusive (Delegates Execute One at a Time) Ordered (Delegates Execute in Queue Order) Send May Invoke Delegate Directly Post May Invoke Delegate Directly
Windows Forms Yes Yes Yes If called from UI thread Never
WPF/Silverlight Yes Yes Yes If called from UI thread Never
Default No No No Always Never
ASP.NET No Yes No Always Always

参考

1) It's all about SynchronizationContext

深入理解 SynchronizationContext的更多相关文章

  1. 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...

  2. SynchronizationContext.Post方法 代替

    http://www.codeproject.com/KB/threads/SynchronizationContext.aspx看吧,不好,就将就的看下我的吧,呵呵!(没有直接翻译,不过大概的思路相 ...

  3. 通过同步上下文方式更新winform中的控件信息

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...

  4. 理解C#中的ExecutionContext vs SynchronizationContext

    原文:https://devblogs.microsoft.com/pfxteam/executioncontext-vs-synchronizationcontext/ 作者:Stephen 翻译: ...

  5. 搞懂 SynchronizationContext(第一部分)【翻译】

    SynchronizationContext -MSDN 很让人失望 我不知道为什么,目前在.Net下关于这个类只有很少的资料.MSDN文档也只有很少的关于如何使用SynchronizationCon ...

  6. 搞懂 SynchronizationContext

    SynchronizationContext -MSDN 很让人失望 我不知道为什么,目前在.Net下关于这个类只有很少的资料.MSDN文档也只有很少的关于如何使用SynchronizationCon ...

  7. 【.NET异步编程系列2】掌控SynchronizationContext避免deadlock

    引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/async异步编程语法糖简化了异步编程方式. 相信很多开发者都看到如下异步编程实践原 ...

  8. 利用SynchronizationContext.Current在线程间同步上下文

    简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线程都附加SynchronizationCon ...

  9. 探究SynchronizationContext在.Net异步编程中的地位

    原文:探究SynchronizationContext在.Net异步编程中的地位 引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/a ...

随机推荐

  1. Ansible_描述角色结构

    一.利用角色构造ansible playbook 1.What's 角色 1️⃣:Ansible角色提供了一种方法,让用户能以通用的方式更加轻松地重复利用Ansible代码. 我们可以在标准化目录结构 ...

  2. otter源码解读(一)

    概览 lib存放的是项目依赖包,由于项目用到的包比较杂,可能有的包已经不在maven仓库中提供了,所以提供了一个lib包,执行里面的install命令,就可以把包安装到本地maven仓库. manag ...

  3. 活动识别API服务开发

    活动识别API服务开发 要使用华为活动识别服务API,需要确保设备已经下载并安装了HMS Core(APK),并将Location Kit的SDK集成到项目中. 指定应用权限 在Android Q以下 ...

  4. GPU编程和流式多处理器(三)

    GPU编程和流式多处理器(三) 3. Floating-Point Support 快速的本机浮点硬件是GPU的存在理由,并且在许多方面,它们在浮点实现方面都等于或优于CPU.全速支持异常可以根据每条 ...

  5. IoU、GIoU、DIoU、CIoU损失函数

    IoU.GIoU.DIoU.CIoU损失函数 目标检测任务的损失函数由Classificition Loss和Bounding Box Regeression Loss两部分构成.目标检测任务中近几年 ...

  6. GVS案例分享|乘新时代姑苏舫号,体验匠心智能控制

    水,是苏州的灵魂,串起苏州的古与今.动与静.金鸡湖景区位于苏州工业园区,总面积11.5平方公里,其中水域面积7.4平方公里. 新时代姑苏舫号,是金鸡湖景区极具苏式特征且规格超高的游览船型.船体分为上下 ...

  7. 三、部署被监控主机-Zabbix Agent

    三.部署被监控主机-Zabbix Agent 1) 源码安装Zabbix agent软件 在2.100和2.200做相同操作(以zabbixclient web1为例). [root@zabbixcl ...

  8. 性能工具之stress工具使用教程(带源码说明)

      stress是一个在linux下的压力测试小工具. 我看到有些人用这个工具来描述一些资源耗尽的场景,也有人用它来做混沌测试中.请使用者要注意,这个工具并不是模拟业务问题的,是模拟系统级问题的.所以 ...

  9. WordPress安装篇(2):用宝塔面板在Windows上安装WordPress

    上一篇文章介绍了如何使用PHPStudy工具在Windows Server环境安装WordPress,接下来介绍一款更加强大的部署WordPress的集成工具--宝塔面板.宝塔面板不仅提供免费版本,还 ...

  10. 【NX二次开发】体素特征相关函数(块、柱、锥、球)

    NX Open允许用户创建和查询所有基本体素特征,通过API函数建立基本体素特征返回的是相应的特征标识,如果需要可以通过函数UG_MODL_ask_feat_body()获得特征对应的实体对象标识.基 ...