- 博客(74)
- 收藏
- 关注
原创 Halcon 学习笔记 #001:读图与显示
💡 在 HDevelop 的 "变量"窗口(一般在界面右下角)里,运行完这一行后你会看到 `Width` 和 `Height` 自动出现了,并且显示了具体的数值。⚠️ 常见坑:很多从 OpenCV 过来的开发者习惯 `(x, y)` = `(列, 行)` 的写法,但 Halcon 是 `(Row, Column)` = `(行, 列)`,顺序反的,一开始很容易搞混。放在 `dev_open_window` 和 `dev_set_part` 之后执行,这样窗口已经准备好了,图片就能正确显示了。
2026-07-26 12:25:16
287
原创 .NET 线程池 工作线程 扩容 + 空闲 + 回收 原理
本文详细解析了.NET线程池的工作机制,主要包含三个核心规则:1)扩容逻辑:任务到达时若线程数小于最小值(默认CPU核心数)立即创建线程,超过后每500ms限流创建1个线程;2)空闲处理:执行完任务的线程进入休眠等待状态,不占用CPU;3)回收机制:超过最小值的线程空闲1秒后销毁,最小值以内的线程永久保留。通过代码示例展示了线程池的扩容限流(500ms/线程)和空闲回收(1秒超时)现象,并提供了完整流程图说明任务处理的生命周期。这种机制既保证了响应速度,又避免了资源浪费。
2026-05-10 10:46:01
489
原创 C# foreach 为什么不能增删、迭代器底层原理、版本号机制、以及所有能遍历中增删的方案
foreach循环本质会被编译器转换为迭代器模式,通过版本号机制确保集合遍历期间不被修改。List内部维护_version字段,任何结构性修改都会使其自增。迭代器初始化时会保存当前版本号,每次MoveNext()都会校验版本一致性,若发现不一致则抛出异常。这种设计是为了避免遍历过程中的漏项、重复或指针失效问题。文章介绍了6种安全修改集合的方法:for倒序遍历、先标记后删除、RemoveAll方法、复制集合快照、使用并发集合以及LinkedList链表操作。其中for倒序和RemoveAll是性能最优的方案。
2026-05-10 09:08:35
661
原创 C# UI 跨线程刷新:Invoke/BeginInvoke 原理与封装
摘要:WinForm/WPF中UI控件只能由UI线程操作,子线程直接修改会抛出跨线程异常。解决方法是通过Invoke/BeginInvoke将UI更新任务交给UI线程执行。Invoke是同步调用会阻塞子线程,BeginInvoke是异步调用不阻塞。WPF中使用Dispatcher实现相同功能。文章提供了封装类简化调用流程,推荐使用BeginInvoke异步方式,并给出封装代码示例。核心原则是:UI操作必须由UI线程执行,通过消息调度机制实现线程安全更新。
2026-05-07 23:07:42
581
原创 Task、async/await 不是多线程,是状态机语法糖
本文解析了C#中async/await的本质,指出它并非多线程技术,而是编译器生成的异步状态机语法糖。编译器将async方法拆分为多个步骤,通过IAsyncStateMachine实现暂停和恢复功能。Task只是异步任务的容器,不代表线程。文章强调异步与多线程的核心区别:异步通过挂起等待实现线程复用,而多线程是并行执行。只有在使用Task.Run时才会创建新线程,而原生异步操作如IO操作通常不占用线程。总结认为async/await是执行模式,多线程是资源调度模式,二者本质不同。
2026-05-05 15:13:40
525
原创 C# 反射、特性、AOP 本质原理
本文解析C#三大核心技术特性:特性(Attribute)、反射(Reflection)和AOP的递进关系。特性是为代码添加标记的语法,编译后存入元数据;反射是运行时读取这些元数据并动态操作类型的能力;AOP则基于反射和动态代理,通过拦截标记特性实现方法调用的横切逻辑处理。三者形成完整技术链:特性提供标记,反射读取标记,AOP利用反射实现动态代理和横切编程。这构成了C#框架(如ASP.NET Core)的核心支柱,支撑了ORM、IOC等高级功能的实现。
2026-05-05 10:22:43
736
原创 C# 泛型:约束、协变逆变、底层模板生成机制
本文系统介绍了C#泛型的核心概念与应用。首先阐述了泛型的基础特性:通过延迟类型指定实现代码复用,确保类型安全并避免装箱拆箱。其次详细解析了泛型约束(where)的五种形式及其组合使用,包括基类、接口、引用类型等约束。重点讲解了协变(out)和逆变(in)机制,说明它们如何通过子父类转换实现类型兼容性。最后揭示了CLR底层的实现原理:引用类型共享代码而值类型独立生成,解释了泛型在性能和内存上的优势。全文从语法到原理层层深入,完整呈现了泛型编程的核心技术体系。
2026-05-04 22:57:56
581
原创 C# 程序集、IL、CLR 执行流程
《C#程序运行机制解析》摘要: 本文系统讲解了C#程序的运行原理。C#代码首先被编译为IL中间语言和元数据,打包成程序集(.exe/.dll)。运行时CLR加载程序集,通过JIT编译器将IL代码即时编译为机器码执行。核心机制包括:1)程序集包含IL代码而非机器码;2)CLR作为运行时环境负责内存管理和安全检查;3)JIT编译器实现首次编译缓存优化。这种架构保证了.NET程序的跨平台性,所有语言最终都转换为统一的IL代码,由CLR统一管理执行。整个过程展现了从源代码到机器码的完整转换链条。
2026-05-04 16:05:02
412
原创 C# 继承、多态、虚方法表(VTable)原理
摘要:继承允许子类复用父类成员并重写方法,多态通过父类引用调用子类实现。C#使用虚方法表(VTable)实现多态:每个类拥有独立VTable,子类复制父类VTable并替换重写方法地址。当父类引用调用虚方法时,CLR通过对象类型指针查找VTable,动态执行子类方法。virtual和override是关键,而new不参与多态。VTable机制确保运行时根据实际对象类型调用正确方法,这是多态的核心实现原理。
2026-05-04 11:41:54
421
原创 C# 结构体 (struct) vs 类 (class) 本质区别 + 栈 / 堆分配
C#中struct和class的核心区别:struct是值类型,默认栈分配(局部变量在栈,作为字段/数组元素时内嵌到堆);class是引用类型,实例始终在堆上。struct通过值拷贝创建独立副本,class通过引用共享对象。struct适合小数据、高频分配场景(如坐标、配置),可避免GC开销;class适合复杂业务、需要继承多态的场景。注意struct赋值给object或接口时会触发装箱操作,导致堆分配和GC开销。选择时应根据数据大小、生命周期和业务需求决定使用struct还是class。
2026-05-04 00:09:58
223
原创 C# 字符串不可变性 + 字符串驻留池原理
本文探讨C#字符串的两个核心特性:不可变性和驻留池机制。字符串不可变性指字符串创建后不能被修改,任何"修改"操作都会创建新对象,这保证了线程安全但可能导致频繁拼接时性能问题(建议使用StringBuilder)。字符串驻留池是CLR维护的全局缓存池,存储相同内容的单个实例,分为编译期自动驻留(字面量)和运行期手动驻留(string.Intern())。两者协同工作:不可变性确保驻留池安全复用内存,驻留池则优化内存使用。需注意动态拼接字符串默认不驻留,而驻留池中的字符串生命周期较长。
2026-05-03 18:43:54
405
原创 C# 变量:生命周期、作用域、变量逃逸
变量本来应该在栈上,但是因为被 “外部引用”,被迫跑到堆上,无法在栈上自动释放→ 这就叫逃逸。逃逸 = 局部变量逃离了它的局部作用域,生命周期被延长了。作用域:变量能被访问的代码范围生命周期:变量在内存中存活的时间变量逃逸:局部变量被迫从栈跑到堆,生命周期被延长逃逸危害:增加 GC 压力,降低性能核心优化:尽量让局部变量不逃逸,留在栈上。
2026-05-03 17:43:38
448
原创 C# 装箱、拆箱 底层原理
装箱:值类型 → 引用类型,堆分配 + 数据拷贝拆箱:引用类型 → 值类型,类型检查 + 数据拷贝回栈成本:装箱 > 拆箱 > 普通赋值优化:用泛型、避免转 object、避免频繁字符串拼接。
2026-05-03 10:12:03
275
原创 栈和堆的概念
值类型放栈上,用完自动亡;引用地址蹲栈上,对象本体住堆仓。一句话 栈就是临时工作台,方法用完就扔,自动清理。字符串、Person 对象的所有数据。栈上:s1、p 只存。
2026-05-02 11:52:21
241
原创 C# 值类型 / 引用类型 内存布局(栈、堆、托管堆)
栈 = 快、自动释放、存值类型 / 引用指针托管堆 = 慢、GC 管理、存引用类型真实数据值类型 = 数据自己存自己引用类型 = 栈存地址,堆存数据class 里的值类型 → 存在堆上。
2026-05-02 11:39:45
447
原创 C#ManualResetEvent
ManualResetEvent = 手动闸门WaitOne()= 等开门Set()= 开门(一直开)Reset()= 手动关门一次打开,所有线程全部通过,必须手动重置才会重新等待适合:多线程统一启动、暂停继续、服务启动等待完整示例:多线程统一放行// 初始:关闭闸门(无信号,WaitOne 会阻塞)Console.WriteLine("=== 启动5个工作线程,全部进入等待 ===");// 开启5个子线程i <= 5;i++)
2026-04-21 22:28:19
458
原创 WPF 从零实现 MVVM 模式:手把手搭建待办事项应用
MVVM 是的缩写,是专门为 WPF/UWP 设计的解耦型架构模式分离界面(View)和业务逻辑(ViewModel)界面不直接操作数据,数据不依赖界面,实现低耦合、可测试、易维护彻底解耦:界面和逻辑分离,修改界面不影响逻辑,修改逻辑不影响界面可测试性:ViewModel 纯逻辑,无界面依赖,可直接写单元测试代码复用:Model、ViewModel 可跨项目、跨页面复用维护性高:职责清晰,找 bug、改功能一目了然符合 WPF 设计理念:原生支持数据绑定、命令绑定,开发效率极高。
2026-04-17 07:22:47
496
原创 欧姆龙 FINS 协议详解与 C# 实现
FINS(Factory Interface Network Service)是欧姆龙(OMRON)专为工业自动化领域设计的现场总线通信协议,用于实现 PLC 之间、PLC 与上位机之间的跨网络数据交互,支持位 / 字数据的读写、强制操作、参数配置等核心功能,是欧姆龙工业通信的核心协议。FINS 协议核心:基于请求 - 响应模型,FINS/TCP 是工程主流实现,需先完成 TCP 连接和 FINS/TCP 握手,再交互指令帧;编码关键。
2026-03-25 11:09:16
1148
原创 MQTT 概念详解与 C# 实战
MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布 / 订阅模式的物联网通信协议,由 IBM 开发,专为低带宽、高延迟、不可靠网络设计(如物联网设备、传感器、移动网络)。轻量级:协议头最小仅 2 字节,占用资源极少发布 / 订阅模式:解耦消息发送者(发布者)和接收者(订阅者)QoS 消息质量:支持 3 级消息可靠性保障持久会话:客户端断开后可恢复会话,避免消息丢失遗嘱消息:客户端异常断开时,代理自动发送预设消息MQTT 核心。
2026-02-22 16:22:12
1084
原创 计算机网络知识(一)
1-19 试解释以下名词:协议栈、实体、对等层、协议数据单元、服务访问点、客户、服务器、客户 - 服务器方式。:实现硬件、软件、数据等资源的共享,如共享打印机、云存储、分布式计算等。:使网络中任意主机之间可以交换信息,实现数据互通,如文件传输、远程登录、视频通话等。
2026-02-05 21:59:38
1182
原创 C#中的AutoUpdater自动更新类
封装核心思想采用 “静态类 + 事件驱动” 封装,对外暴露极简的配置项和启动方法,内部封装了网络请求、XML 解析、版本对比、UI 交互、进程管理等复杂逻辑,开发者无需关心底层实现,只需配置参数即可快速集成自动更新功能。关键设计亮点(存储)、(认证)等接口解耦具体实现,支持自定义扩展;场景适配:自动识别 WinForms/WPF、HTTP/FTP,兼容同步 / 异步检查,覆盖强制更新、跳过、稍后提醒等全场景;异常处理:内部捕获关键异常,通过配置 / 事件可控输出,保证应用稳定性。使用核心。
2026-01-21 23:51:20
1000
原创 C#状态机
状态机(Finite State Machine, FSM,又称有限状态机)是一种数学模型和编程思想,用于描述一个对象(或系统)在其生命周期内的有限个状态,以及这些状态之间的转移规则、触发转移的事件 / 条件,还有状态转移过程中(或处于某个状态时)需要执行的动作 / 行为。简单理解:它就像对象的 “行为剧本”,规定了对象在什么状态下,遇到什么事情,应该切换到什么新状态,同时要做什么事。状态机是描述对象有限状态、转移规则、事件和动作的模型,核心价值是解决复杂状态切换的逻辑混乱;
2026-01-12 22:39:50
1233
原创 C# 动态编程(基于 dynamic 类型)
C# 4.0 引入 类型,其核心是运行时绑定(动态绑定),而非编译时绑定(静态绑定)。有些场景下,对象的结构在编译时无法确定,典型场景包括:C# 4.0 中, 支持 4 种运行时绑定逻辑:反射的核心是 “运行时查找 / 调用类型成员”,但原生反射代码繁琐; 可以用更简洁的语法实现反射功能。4.1 原生反射 vs 反射原生反射(繁琐): 反射(简洁):4.2 反射的代码示例输出:4.3 反射的注意事项 不是 “新类型”,而是告诉编译器 “运行时再处理绑定” 的指令,其底层是 。
2026-01-08 23:55:26
1146
原创 C#中的CIL(公共中间语言)
CIL(Common Intermediate Language,公共中间语言)也常被称为 MSIL(Microsoft Intermediate Language),是.NET 框架 /.NET Core/.NET 5 + 体系中介于高级语言(C#/VB.NET等)和机器码之间的中间语言。核心定位:C# 代码不会直接编译成 CPU 能执行的机器码,而是先编译成 CIL;
2026-01-07 23:23:54
1375
原创 C# 调用 Win32 API
Win32 API(Windows 32-bit Application Programming Interface)是微软为 Windows 操作系统提供的底层编程接口,包含了操作系统的核心功能(如窗口管理、文件操作、进程控制、内存管理、系统信息获取等),本质上是一组用 C/C++ 编写的原生函数。
2025-12-23 23:25:47
900
原创 C#中的服务注册剖析
服务注册是.NET 依赖注入(DI)体系中的核心操作,本质是将服务类型(接口 / 抽象类)与具体实现类型、生命周期绑定,并存储到 DI 容器中的过程。服务类型:对外暴露的抽象契约(通常是接口 / 抽象类),比如。实现类型:服务类型的具体实现类,比如。DI 容器:存储服务注册信息的 “容器”,程序运行时可从中 “取出”(解析)服务实例。生命周期:决定 DI 容器创建服务实例的规则,是服务注册的核心属性。
2025-12-18 22:39:37
810
原创 线程同步的意义
C# 线程同步的核心是控制共享资源的访问顺序技术核心作用适用场景lockMonitor互斥访问临界区大多数共享资源同步简化锁管理C# 13 + 的高性能同步volatile保证可见性 / 有序性简单变量的线程间状态同步原子操作简单数值的递增 / 交换Mutex跨进程同步多进程共享资源重新发送事件减少锁竞争高并发场景的锁重试线程独立副本每个线程的私有状态。
2025-12-17 23:07:40
939
原创 C# 反射与泛型深度结合详解
反射(Reflection)是 C# 的 “元编程” 能力,允许程序在获取类型信息、调用方法、创建实例;泛型(Generic)则是 “类型参数化”,实现类型安全的代码复用。两者结合可突破静态泛型的限制,实现,是框架开发(如 DI 容器、ORM、序列化)的核心技术。本文将从 “基础概念→核心 API→分场景超详细案例→底层原理→避坑指南” 全维度讲解,所有案例均为可直接运行的控制台程序,每一行代码都附带注释和原理说明。
2025-12-16 23:47:38
819
原创 C# 基于 HSL 与基恩士 PLC 通信
HSL(HslCommunication)是国产工业通信框架,支持主流 PLC / 仪表 / 变频器通信,对基恩士 PLC 的 MC 协议做了高度封装,无需手动解析协议帧,只需调用 API 即可完成通信。
2025-12-15 23:33:45
1756
原创 C# HSL 与欧姆龙 CIP 协议(EtherNet/IP)的详细通信
CIP 协议的全称是 Common Industrial Protocol(通用工业协议),是一种面向工业自动化领域的开放、多厂商兼容的应用层通信协议,由 ODVA(Open DeviceNet Vendors Association)组织管理和维护。它的核心目标是实现工业设备之间的无缝数据交互,涵盖控制、配置、诊断等全生命周期功能。CIP 是一个与底层物理网络无关的应用层协议,可以运行在多种工业网络上,形成不同的工业总线标准,典型包括:CIP 采用对象模型来描述工业设备的功能,每台设备都被抽象为一系列标准
2025-12-14 23:27:55
2060
原创 TPL如何自动调整执行效率
TPL 是 .NET Framework 4.0 及以上版本(.NET Core/.NET 5+ 全面继承并增强)内置的并行编程核心库,隶属于命名空间,本质是对底层线程、线程池、同步原语的高度抽象封装。让开发者无需手动管理线程(创建、销毁、调度),即可高效利用多核 CPU 资源,实现任务级并行,同时自动适配运行时的系统资源状态,动态调整执行效率。传统手动线程管理(Thread类)存在高开销、易出错(如线程安全、死锁)、无法自适应系统负载的问题;
2025-12-13 21:42:31
591
原创 C#中结构(Struct)
结构(struct)是 C# 中一种值类型数据结构,用于封装小型相关数据。它与类(class)类似,可包含字段、属性、方法等成员,但本质是值类型(存储在栈上),而类是引用类型(存储在堆上)。核心特点值类型,赋值时直接复制数据(而非引用);适合存储小型、简单的数据(如坐标、颜色、日期等);不能被继承(密封类型),但可实现接口。// 基本语法访问修饰符 struct 结构名 : 接口1, 接口2...// 成员(字段、属性、方法、构造函数等)示例:定义一个表示二维坐标的结构。
2025-10-12 20:50:33
1558
原创 C#中堆和栈的概念
对比项栈(Stack)堆(Heap)存储内容值类型数据、引用类型的引用引用类型的实际数据管理方式编译器自动分配 / 释放垃圾回收器(GC)自动管理速度极快(连续内存操作)较慢(需查找空闲内存)空间大小小(几 MB)大(GB 级)顺序先进后出,连续存储无序,随机存储典型用途临时变量、方法参数、局部变量对象、字符串、数组等大数据解释为什么值类型赋值是 “复制值”,引用类型赋值是 “复制地址”(如int a = b和的差异)。
2025-10-12 17:48:01
1064
原创 C#泛型类
泛型类是可以支持多种数据类型的类,它允许在定义类时不指定具体数据类型,而是在使用时动态指定。核心作用:避免重复编写相似代码(如分别为intstringobject写相同逻辑的类),同时保证类型安全(编译时检查类型,避免装箱拆箱)。// 基本语法:类名后加<T>,T是类型参数(可自定义名称,如TData、TItem)public class 类名<T>// 可以使用T作为属性、方法参数、返回值的类型代码复用:一份代码支持所有类型,无需重复编写类型安全:编译时检查类型,避免运行时类型转换错误。
2025-10-12 15:28:23
485
原创 WPF-数据绑定(Binding)
减少了 UI 与数据之间的胶水代码实现了数据与 UI 的自动同步使代码结构更清晰,关注点分离支持多种绑定场景和高级功能通过实现和使用,可以构建响应式的 WPF 应用程序,让 UI 始终反映最新的数据状态。
2025-08-31 23:51:45
1553
原创 C# 泛型(Generics)详解
类型安全:编译时检查类型,避免运行时类型转换错误。性能优化:减少装箱 / 拆箱操作,尤其对值类型更高效。代码复用:一套逻辑适配多种类型,减少重复代码。灵活性:结合约束、协变、逆变等特性,可适应复杂场景。
2025-08-13 08:46:10
1913
原创 C#Attribute(特性)的定义与使用
1.1 定义Attribute 是一种“声明式元数据(declarative metadata)”机制。• 附加位置:程序集、模块、类型、字段、属性、方法、方法参数、方法返回值、事件、泛型参数、局部变量、本地函数、Lambda 表达式、甚至表达式树。• 本质:编译器把特性的实例化信息序列化到元数据表中;运行期可通过反射读取,或供编译器、分析器、Source Generator 消费。• 语法:用方括号[...]写在目标实体前面,可简写、组合、带命名参数。1.2 与注释/ XML 的区别。
2025-08-09 08:39:16
1525
原创 C#中的锁与信号量
lock:适合简单的独占访问场景,使用简单,性能好,是多线程同步的首选方案;:适合需要限制并发数量的场景(如连接池、限流),支持异步,灵活性更高。
2025-08-07 08:38:11
1407
原创 C#中的Task的概念与使用
封装一个异步操作,可用于执行耗时任务(如网络请求、文件 IO、数据库操作等),避免阻塞主线程,提高程序响应性。命名空间,是 .NET 异步编程模型(APM)的核心组件。是 C# 中用于表示异步操作的对象,属于。Task 有以下几种核心状态(通过。任务中抛出的异常会被包装在。方法的返回类型通常为。(仅用于事件处理)。
2025-08-06 08:42:54
3288
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅