当前位置: 首页 > news >正文

C# .Net 中的同步上下文

.Net 中的同步上下文

【文 / 张赐荣】

什么是同步上下文?
同步上下文(SynchronizationContext)是一个抽象类,它提供了一个基本的功能,用于在不同的同步模型中传播一个同步操作。 同步上下文表示一个代码执行的位置,它可以将传递给它的Send或Post方法的委托调用到该位置。 Send方法是同步的,Post方法是异步的。
每个线程都可以有一个与之关联的同步上下文实例。可以通过调用静态方法SynchronizationContext.SetSynchronizationContext来将运行线程与一个同步上下文关联,也可以通过SynchronizationContext.Current属性来查询运行线程的当前同步上下文。
同步上下文并不一定代表一个特定的线程,它也可以将委托的调用转发到任何多个线程(例如,到一个线程池工作线程),或者(至少理论上)到一个特定的CPU核心,甚至到另一个网络主机。委托最终运行在哪里取决于使用的同步上下文的类型。

同步上下文的作用
同步上下文的目的是让公共语言运行时(CLR)的内部异步/同步操作能够在不同的同步模型中正确地工作。 这个模型也简化了托管应用程序在不同的同步环境中工作时必须遵循的一些要求。
例如,在Windows Forms应用程序中,只有一个主UI线程,它负责创建和更新窗体和控件。如果在其他线程上直接访问UI元素,就会导致异常或不一致的行为。因此,Windows Forms会在创建首个窗体的线程上安装一个WindowsFormsSynchronizationContext,它会将委托放到UI线程上执行。 这样,就可以在其他线程上异步地执行一些耗时或阻塞的操作,然后通过Post方法将结果传递给UI线程同步执行更新界面的操作。

同步上下文和异步编程
.NET提供了一些异步编程模式和语法糖,例如async/await、Task、TaskCompletionSource等,它们都依赖于同步上下文来实现正确和高效地异步操作。
当使用async/await编写异步代码时,编译器会将方法分割成两部分:第一部分是从方法开始到第一个await表达式之前的代码;第二部分是从第一个await表达式之后到方法结束的代码。第二部分被包装成一个委托,并传递给第一个await表达式所等待的任务(Task)作为其完成时要执行的续发。
当任务完成时,它会检查当前线程的同步上下文,并将委托调用到该同步上下文上。 这样,就可以保证异步续发在与原始方法相同的位置执行,例如在UI线程或请求线程上。这对于访问一些需要特定线程或上下文的资源是很有用的。
但是,有时候我们并不需要异步续发在原始方法的位置执行,而是希望它在默认的线程池上执行,以提高性能和并发度。这时候,我们可以使用ConfigureAwait方法来指定是否要捕获当前的同步上下文。例如:

var task = DoNavigationAsync ();
await task.ConfigureAwait (false); // 不捕获当前的同步上下文
MessageBox.Show (\"Navigation done!\"); // 可能在其他线程上执行

这样,异步续发就不会使用当前的同步上下文,而是使用默认的任务调度器(TaskScheduler.Default),它会将委托调用到一个线程池工作线程上。 这样做的好处是可以避免一些潜在的死锁或性能问题。
另一种异步编程模式是使用Task和TaskCompletionSource来创建和完成任务。Task表示一个异步操作的结果,它可以有三种状态:未完成、成功完成或失败完成。TaskCompletionSource是一个包装了一个任务的类,它提供了一种设置任务状态和结果的方法。
当我们使用TaskCompletionSource创建一个任务时,我们可以指定一个任务创建选项(TaskCreationOptions),其中有一个选项是HideScheduler,它表示不要从当前环境中获取任务调度器。 这样,当我们使用ContinueWith方法为任务添加续发时,就不会使用当前的同步上下文,而是使用默认的任务调度器。例如:

var tcs = new TaskCompletionSource<int> (TaskCreationOptions.HideScheduler);
var task = tcs.Task;
task.ContinueWith (t => Console.WriteLine (t.Result)); // 在线程池上执行
tcs.SetResult (42); // 完成任务

如果我们不指定HideScheduler选项,那么ContinueWith方法就会使用当前的同步上下文(如果存在)来执行续发。

总结
同步上下文是.NET中一个重要的概念,它影响了异步编程模式和语法的行为和效果。不同的.NET平台和环境实现了不同的同步上下文,以适应不同的同步模型。理解同步上下文的作用和用法,可以帮助我们编写正确和高效的异步代码。
 

相关文章:

C# .Net 中的同步上下文

.Net 中的同步上下文 【文 / 张赐荣】 什么是同步上下文&#xff1f; 同步上下文&#xff08;SynchronizationContext&#xff09;是一个抽象类&#xff0c;它提供了一个基本的功能&#xff0c;用于在不同的同步模型中传播一个同步操作。 同步上下文表示一个代码执行的位置&a…...

3分钟入门:Flex 布局

flex 布局原理 全称 flexible box&#xff0c;弹性布局。 如何开启&#xff1a;为元素添加 display: flex。 开启 flex 布局的元素&#xff0c;称为 flex 容器&#xff08;flex container&#xff09;&#xff0c;其子元素成为容器成员&#xff0c;称为 flex 项目。 flex 布…...

我想知道,就目前形势而言,学java好还是C++好?

前言 就现实点看看&#xff0c;可以对比现在Java和C的市场占有率&#xff0c;可以看到&#xff0c;到目前为止&#xff0c;Java在国内编程语言的市场仍然是占据着大头&#xff0c;在招聘当中Java的人数占有率仍然是遥遥领先于C&#xff0c;Java目前开阔的市场以及其巨大的岗位…...

Mysql 管理

目录 0 课程视频 1 系统数据库 -> 安装完mysql ->自带四个数据库 2 常用工具 -> 写脚本用 2.1 mysql 客户端工具 2.2 mysqladmin 2.3 mysqlbinlog -> 二进制日志 -> 运维讲解 2.4 mysqlshow 2.5 mysqldump 备份用 ->导出 2.6 mysqlimport/source -…...

C#基础(算术运算符)

作用 算术运算符 是用于 数值类型变量计算的运算符 它的返回结果是数值 赋值符号 // // 关键知识点&#xff1a; // 先看右侧 再看左侧 把右侧的值赋值给左侧的值 int myAge 18; 算术运算符 加 // 用自己计算 先算右侧结果 在赋值给左侧变量 int i 1; i i 2; …...

BM43-包含min函数的栈

题目 定义栈的数据结构&#xff0c;请在该类型中实现一个能够得到栈中所含最小元素的 min 函数&#xff0c;输入操作时保证 pop、top 和 min 函数操作时&#xff0c;栈中一定有元素。 此栈包含的方法有&#xff1a; push(value):将value压入栈中pop():弹出栈顶元素top():获取…...

[学习笔记] [机器学习] 3. KNN( K-近邻算法)及练习案例

视频链接数据集下载地址&#xff1a;《3. KNN及练习案例》配套数据集 1. K-近邻算法(KNN)概念 学习目标&#xff1a; 掌握K-近邻算法实现过程知道K-近邻算法的距离公式知道K-近邻算法的超参数 K K K值以及取值问题知道kd树实现搜索的过程应用KNeighborsClassifier实现分类知…...

React Hooks 钩子函数错误用法,你还在犯这些错误吗

React Hooks 常见错误 前言 本片文章主要是在写react hooks的时候&#xff0c;遇到的常见错误的写法&#xff0c;和错误。也是一个对只是的巩固和总结。 错误一 上代码&#xff1a;正确写法 function TestReactHooksError() {const [test, setTest] useState(test);useEff…...

tpm2-tools源码分析之tpm2_evictcontrol.c(1)

TPM 2.0中的tpm2_evictcontrol命令对应的源文件就是tpm2_evictcontrol.c&#xff0c;该文件位于tpm2-tools/tools/下&#xff0c;一共有339行&#xff08;版本5.5&#xff09;。 tpm2_evictcontrol的功能是使一个被加载的密钥持久保存、或者从TPM中移除一个持久密钥。命令描述…...

SpringCloud_OpenFeign服务调用和Resilience4J断路器

文章目录 一、负载均衡概论1、服务器负载均衡2、客户端负载均衡3、客户端负载均衡策略(SpringCloudRibbon)4、客户端负载均衡策略(SpringCloudLoadBalancer) 二、SpringCloudOpenFeign服务调用1、OpenFeign服务调用的使用2、OpenFeign服务调用的日志增强3、OpenFeign服务调用超…...

【C++】switch 语句

目录 1、缘起 2、笔记整理 3、if 和 switch 区别 4、总结 1、缘起 最近&#xff08;2023-04-29&#xff09;在 BiliBili 黑马程序员学习 C 编程语言&#xff0c;今天学习到了 switch 语句。以前在学习 C 语言 的时候&#xff0c;对这块知识点掌握的不是很好&#xff0c;…...

【Database-06】Centos 9 安装docker版的Oceanbase

1、安装docker 1.1、卸载旧版本 旧版本的 Docker 被称为docker或docker-engine。如果安装了这些&#xff0c;卸载它们以及相关的依赖项。 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotat…...

TiDB Operator 和 Operator Dashboard

TiDB Operator 和 Operator Dashboard V1TiDB Operator概念实现 Operator Dashboard概念实现 V2思路实例代码TiDB ARM OperatorTiDB ARM Operator Dashboard V1 为了演示如何编写 TiDB Operator 和 Operator Dashboard&#xff0c;我们将分别介绍它们的概念和实现。 TiDB Ope…...

计算机网络闲谈01——QUIC协议

计算机网络闲谈01——QUIC协议 预备知识 重传机制 RTT 一个连接的往返时间 RTO 重传超时时间 RTT和RTO 的关系是&#xff1a;由于网络波动的不确定性&#xff0c;每个RTT都是动态变化的&#xff0c;所以RTO也应随着RTT动态变化。 流量控制 对发送方发送速率的控制 称之为…...

楼层滚动效果(超级简单,易懂)

系列文章目录 文章目录 系列文章目录一、楼层滚动效果图如下1. 下图是纯Css实现的楼层滚动2.通过Js优化后的楼层滚动如下图(&#x1f339;&#x1f339;) 二、楼层滚动&#xff08;Css实现&#xff09;1.滚动原理2.代码如下 三、楼层滚动&#xff08;JsCss优化后的楼层滚动&…...

FPGA、 CPU、GPU、ASIC区别

一、为什么使用 FPGA&#xff1f; 众所周知&#xff0c;通用处理器&#xff08;CPU&#xff09;的摩尔定律已入暮年&#xff0c;而机器学习和 Web 服务的规模却在指数级增长。 人们使用定制硬件来加速常见的计算任务&#xff0c;然而日新月异的行业又要求这些定制的硬件可被重新…...

ChatGPT 之父承认 GPT-5 并不存在,为什么 OpenAI 总是这么实诚?|万字详述

ChatGPT 诞生前传 来源: 爱范儿 微信号&#xff1a;ifanr 最近&#xff0c;OpenAI 的 CEO Sam Altman 在一场公开会议上为 GPT-5 辟谣。 他声称 OpenAI 并没有在训练 GPT-5&#xff0c;而是一直基于 GPT-4 做别的工作。 OpenAI 是一家非常有趣的机构&#xff0c;和微软、Go…...

华为交换机配置telnet登录图文教程

一、配置交换机管理vlan和地址&#xff0c;配置交换机接口 1.关闭多余的信息提示&#xff1a; [Huawei]undo in en Info: Information center is disabled. [Huawei] 2.交换机配置 在工作中通过Telnet方式登录交换机进行设备登录管理能更加便利&#xff0c;不需要到机房里…...

Linux:网络基础1

网络协议分层 所有网络问题&#xff0c;本质都是通信距离变长了&#xff0c;为了尽可能减少通信成本&#xff0c;定制了协议。 协议分层的优势&#xff1a; 软件设计方面的优势 - 低耦合 一般我们的分层依据: 功能比较集中&#xff0c;耦合度比较高的模块-- 一层 &#xff0c…...

Matlab对日期变量和时间变量的管理

Matlab2012a内置了三个函数 datanumdatevecdatestr 靠这三个函数&#xff0c;可以基本实现日期变量和时间变量的管理。下面直接来看。 &#xff08;1&#xff09;datanum 这个函数用来将字符串&#xff0c;日期矢量转为通用日&#xff08;数值型&#xff09;。所谓的通用日…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...