深入理解 SynchronizationContext
深入理解 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.Invoke 或 Dispatcher.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的更多相关文章
- 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...
- SynchronizationContext.Post方法 代替
http://www.codeproject.com/KB/threads/SynchronizationContext.aspx看吧,不好,就将就的看下我的吧,呵呵!(没有直接翻译,不过大概的思路相 ...
- 通过同步上下文方式更新winform中的控件信息
SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...
- 理解C#中的ExecutionContext vs SynchronizationContext
原文:https://devblogs.microsoft.com/pfxteam/executioncontext-vs-synchronizationcontext/ 作者:Stephen 翻译: ...
- 搞懂 SynchronizationContext(第一部分)【翻译】
SynchronizationContext -MSDN 很让人失望 我不知道为什么,目前在.Net下关于这个类只有很少的资料.MSDN文档也只有很少的关于如何使用SynchronizationCon ...
- 搞懂 SynchronizationContext
SynchronizationContext -MSDN 很让人失望 我不知道为什么,目前在.Net下关于这个类只有很少的资料.MSDN文档也只有很少的关于如何使用SynchronizationCon ...
- 【.NET异步编程系列2】掌控SynchronizationContext避免deadlock
引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/async异步编程语法糖简化了异步编程方式. 相信很多开发者都看到如下异步编程实践原 ...
- 利用SynchronizationContext.Current在线程间同步上下文
简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线程都附加SynchronizationCon ...
- 探究SynchronizationContext在.Net异步编程中的地位
原文:探究SynchronizationContext在.Net异步编程中的地位 引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/a ...
随机推荐
- Ansible_编写Playbook文件
一.Playbook的实施 1.Ansible playbook与临时命令概述: 临时命令可以作为一次性命令对一组目标主机运行一项简单的任务 play是针对清单中选定的主机运行的一组有序任务.play ...
- 有关fgets和fcntl的讨论-待整理更新
问题引出 一个client程序:select 超时监听 sockfd套接字 和 STDIN_FILENO标准输入:若sockfd可读则接收server报文:若标准输入可读(按下回车),则开始用fget ...
- 8.5-7 mkfs、dumpe2fs、resize2fs
8.5 mkfs:创建Linux文件系统 mkfs命令用于在指定的设备(或硬盘分区等)上创建格式化并创建文件系统,fdisk和parted等分区工具相当于建房的人,把房子(硬盘),分成几居室( ...
- 网上的说TB6560存在的问题
https://www.amobbs.com/thread-5506456-2-1.html
- Centos双网卡配置默认路由
Centos6.5 双网卡,我们只需要一个默认路由,如果两个都有或都没有会有一系列的问题 [root@centos]# vi /etc/sysconfig/network修改以下内容NETWORKIN ...
- GO学习-(31) Go语言操作Elasticsearch
Elasticsearch 本文简单介绍了ES.Kibana和Go语言操作ES. Elasticsearch 介绍 Elasticsearch(ES)是一个基于Lucene构建的开源.分布式.REST ...
- arm,asic,dsp,fpga,mcu,soc各自的特点
arm,asic,dsp,fpga,mcu,soc各自的特点 人工智能受到越来越多的关注,许多公司正在积极开发能实现移动端人工智能的硬件,尤其是能够结合未来的物联网应用,对于移动端人工智能硬件的实现方 ...
- 使用OneFlow搭建神经网络
使用OneFlow搭建神经网络 在 识别 MNIST 手写体数字 的例子中,通过 flow.layers 和 flow.nn 中提供的接口搭建了一个简单的 LeNet 网络.下面,将通过LeNet来介 ...
- ISP算法高水平分析(下)
ISP算法高水平分析(下) 十.LSC(Lens Shade Correction)------镜头阴影矫正 Lens Shading指画面四角由于入射光线不足形成的暗角,同时,由于不同频率的光折射 ...
- CUDA运行时 Runtime(一)
CUDA运行时 Runtime(一) 一. 概述 运行时在cudart库中实现,该库通过静态方式链接到应用程序库cudart.lib和libcudart.a,或动态通过cuda ...