当前位置: 首页 > 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.dtcms.com/a/279870.html

相关文章:

  • 微美全息借区块链与DRL算法打造资源管理协同架构,达成边缘计算与区块链动态适配
  • Function-——函数中文翻译渊源及历史背景
  • 学习笔记(35):了解原理:从密度到了解概率密度
  • iperf3 网络带宽测试工具学习
  • 国内隧道IP代理技术解析:原理、优势与实战应用
  • 网络地址转换(NAT)与单臂路由实验
  • 2.逻辑回归、Softmax回归
  • 智能节气装置
  • 记录网络切换时同步操作
  • TypeScript 配置全解析:tsconfig.json、tsconfig.app.json 与 tsconfig.node.json 的深度指南
  • JJ20 Final Lap演唱会纪念票根生成工具
  • 信息收集的基本流程
  • 大模型呼叫系统选型指南
  • 【Linux】Linux 操作系统 - 28 , 进程间通信(四) -- IPC 资源的管理方式_信号量_临界区等基本概念介绍
  • 递推预处理floor(log_2{n})
  • Class9简洁实现
  • HashMap的put过程以及hashMap的简单介绍
  • kt 中商品的金额字段使用double 还是 bigdecimal
  • 动态规划题解——最长递增子序列【LeetCode】记忆化搜索方法
  • 【每日刷题】杨辉三角
  • Git根据标签Tag强制回滚版本
  • 面试常问:如何在一个长度为n的无序数据快速获取前k个数值
  • 网络传输过程
  • GaussDB between的用法
  • 光伏板如何最大化铺设?
  • 【PostgreSQL异常解决】`PostgreSQL`异常之类型转换错误
  • 记录自己在将python文件变成可访问库文件是碰到的问题
  • vert.x 官网docs, vert.x中文文档地址 vertx文档
  • 文心4.5开源之路:引领技术开放新时代!
  • 【前端:Typst】--let关键字的用法