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

C#中发布订阅的阻塞非阻塞

在 C# 中,事件的发布和订阅机制遵循以下规则:

1. 默认行为:同步执行,阻塞发布线程

如果事件订阅者(主线程)的处理方法是同步的,子线程在发布事件后会等待所有订阅者执行完毕,才会继续执行后续代码。

Block_Test.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace WindowsFormsApp1
{public class Block_Test{// 定义一个委托类型public delegate void MyEventHandler(object sender, EventArgs e);// 定义一个事件public event MyEventHandler MyEvent;// 触发事件的方法public void TriggerEvent(){Console.WriteLine($"thread--{Thread.CurrentThread.ManagedThreadId}--");Console.WriteLine("事件触发前");// 触发事件,会调用所有注册的处理程序MyEvent?.Invoke(this, EventArgs.Empty);Console.WriteLine("事件触发后");}}
}

program.cs

         public Form1(){InitializeComponent();Console.WriteLine($"Form1--{Thread.CurrentThread.ManagedThreadId}--");signalThread = new Thread(publisher.TriggerEvent);signalThread.IsBackground = true; // 设置为后台线程//OnEventHandlerAsync();//异步订阅(不阻塞发布线程)// 注册事件处理程序publisher.MyEvent += Program_MyEvent;//阻塞发布线程// 触发事件//program.TriggerEvent();}public void Program_MyEvent(object sender, EventArgs e){//下面的代码发布线程会阻塞if (this.InvokeRequired)  // 判断是否需要切换线程{// 需要切换到主线程this.Invoke(new EventHandler(Program_MyEvent), sender, e);return;}Console.WriteLine($"mian--{Thread.CurrentThread.ManagedThreadId}--");Console.WriteLine("事件处理程序执行中");// 模拟一些工作System.Threading.Thread.Sleep(10000);this.button1.Text = "button2";Console.WriteLine("事件处理程序执行完毕");}

2. 异步执行:发布后立即继续(不阻塞)

如果需要子线程在发布事件后立即继续执行,可以在订阅时使用异步处理

        public Form1(){InitializeComponent();Console.WriteLine($"Form1--{Thread.CurrentThread.ManagedThreadId}--");signalThread = new Thread(publisher.TriggerEvent);signalThread.IsBackground = true; // 设置为后台线程OnEventHandlerAsync();//异步订阅(不阻塞发布线程)// 注册事件处理程序//publisher.MyEvent += Program_MyEvent;//阻塞发布线程// 触发事件//program.TriggerEvent();}private void OnEventHandlerAsync(){// 异步订阅(不阻塞发布线程)publisher.MyEvent += async (sender, e) =>{await Task.Run(() =>{Console.WriteLine("主线程:异步处理事件(模拟耗时操作)");Thread.Sleep(10000);Console.WriteLine("主线程:异步事件处理完成");});};}

http://www.lryc.cn/news/588157.html

相关文章:

  • Spring Boot + Vue2 实现腾讯云 COS 文件上传:从零搭建分片上传系统
  • QT——信号与槽
  • Zabbix在MySQL性能监控方面的运用
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十五课——基于sobel算子边缘检测的FPGA实现
  • Spring核心概念指南
  • Linux部署Mysql
  • (LeetCode 每日一题) 1290. 二进制链表转整数 (链表+二进制)
  • 微前端框架深度对决:qiankun、micro-app、wujie 技术内幕与架构选型指南
  • 艺术总监的构图“再造术”:用PS生成式AI,重塑照片叙事框架
  • 网络协议和基础通信原理
  • Bash vs PowerShell | 从 CMD 到跨平台工具:Bash 与 PowerShell 的全方位对比
  • 隐藏源IP的核心方案与高防实践
  • VNC和Socket
  • IP相关
  • 水务工程中自动化应用:EtherNet/IP转PROFIBUS DP连接超声波流量计
  • 从0到1实现Shell!Linux进程程序替换详解
  • 创客匠人谈知识变现:IP 变现的核心,在于执行闭环的落地
  • 更改elementui 图标 css content
  • 修改crontab默认编辑器
  • 多线程是如何保证数据一致和MESI缓存一致性协议
  • 一种用于医学图像分割的使用了多尺寸注意力Transformer的混合模型: HyTransMA
  • 从“有”到“优”:iPaaS 赋能企业 API 服务治理建设
  • FastAPI-P1:Pydantic模型与参数额外信息
  • Linux中使用云仓库上传镜像和私库制作Registry
  • Android系统的问题分析笔记 - Android上的调试方式 debuggerd
  • 超导探索之术语介绍:费曼图(Feynman Diagram)
  • 【基础架构】——架构设计流程第三步(评估和选择备选方案)
  • 8.服务通信:Feign深度优化 - 解密声明式调用与现代负载均衡内核
  • 现代数据平台能力地图:如何构建未来数据平台的核心能力体系
  • LSV负载均衡