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

深入C#异步编程基石:BeginInvoke与EndInvoke全解析

🔧 核心机制解析

1. BeginInvoke:异步执行触发器

delegate long MyDel(int first, int second);
MyDel del = Sum; 
IAsyncResult iar = del.BeginInvoke(3, 5, null, null); // 关键调用 
  • 参数结构:
    • 前N位:委托方法实际参数(如示例中的3和5)
    • 最后两位:
      • AsyncCallback callback:完成回调委托
      • object state:传递给回调的上下文对象
  • 底层行为:
    • 从线程池获取工作线程执行目标方法
    • 立即返回IAsyncResult对象(非阻塞)

2. EndInvoke:资源回收与结果获取

long result = del.EndInvoke(iar); // 必须调用!
  • 三重职责:
    1. 阻塞等待异步操作完成(若未完成)
    2. 获取返回值/输出参数
    3. 释放线程资源(避免泄漏的关键)
  • 异常机制:异步方法中的异常在EndInvoke时抛出

⚠️ 黄金法则:每个BeginInvoke必须配对EndInvoke


🧩 三大异步模式实战

模式1:等待直到完成(阻塞式)

IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
// ...主线程执行其他任务...
long result = del.EndInvoke(iar); // 阻塞等待结果 
  • 适用场景:需异步执行但必须等待结果的同步逻辑
  • 特点:简单直接,但可能造成线程阻塞

模式2:轮询检测(主动控制)

while (!iar.IsCompleted) 
{Console.WriteLine("处理其他任务...");Thread.SpinWait(1_000_000); // 避免CPU空转
}
long result = del.EndInvoke(iar);
  • 优势:主线程完全掌控检测节奏
  • 陷阱:频繁检查IsCompleted可能导致性能损耗

模式3:回调模式(事件驱动)

// 回调方法定义 
void Callback(IAsyncResult iar)
{AsyncResult ar = (AsyncResult)iar;MyDel del = (MyDel)ar.AsyncDelegate;long result = del.EndInvoke(iar);// 处理结果...
}// 发起异步调用
del.BeginInvoke(3, 5, Callback, null);
  • 关键技术:
    • 通过IAsyncResult.AsyncDelegate获取原始委托(需引用System.Runtime.Remoting.Messaging
    • 使用state参数传递上下文
  • 优势:完全非阻塞,适合事件驱动架构

⚙️ IAsyncResult深度揭秘

AsyncResult类结构

  • 核心属性:
    • IsCompleted → 异步操作状态检测
    • AsyncState → 获取传递的上下文对象
    • AsyncWaitHandle → 等待句柄(用于WaitOne等操作)
  • 类型转换技巧:
    AsyncResult ar = (AsyncResult)iar; // 实际是AsyncResult实例
    MyDel del = (MyDel)ar.AsyncDelegate; // 获取原始委托
    

💡 现代异步编程启示

虽然BeginInvoke/EndInvoke已被Task取代,但其设计思想影响深远:

  1. 异步状态封装 → Task.Status属性
  2. 回调机制 → Task.ContinueWith方法
  3. 结果获取 → Task.Result属性

等效Task实现:

// 传统模式
del.BeginInvoke(3, 5, Callback, null);// 现代替代方案 
Task.Run(() => Sum(3, 5)).ContinueWith(t => Callback(t.Result));

🚀 实战避坑指南

1. 资源泄漏风险

未调用EndInvoke会导致线程资源无法回收 → 务必配对使用

2. 跨线程访问陷阱

// 错误示例(WinForms场景)
void Callback(IAsyncResult iar) {textBox.Text = result.ToString(); // 跨线程访问异常 
}// 正确方案
void Callback(IAsyncResult iar) {this.Invoke(() => textBox.Text = result.ToString());
}

3. 异常处理规范

try {del.EndInvoke(iar);
}
catch (Exception ex) {// 捕获异步方法所有异常Log.Error("异步操作失败", ex);
}

4. 上下文传递技巧

var context = new { RequestId = Guid.NewGuid() };
del.BeginInvoke(3, 5, Callback, context);// 回调中获取 
var ctx = (dynamic)iar.AsyncState;
Console.WriteLine(ctx.RequestId);

历史镜鉴:BeginInvoke/EndInvoke如同异步编程的“活化石”,虽已淡出主流,但其设计思想仍在Task和async/await中延续。理解过去,方能更好驾驭未来!

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

相关文章:

  • 使用ceph-deploy安装和配置RADOS Gateway (RGW)并使用S3访问集群
  • 串口超时参数深度解析:ReadTotalTimeoutMultiplier、ReadIntervalTimeout等
  • JVM宝典
  • 在IDEA中设置SQL解析作用域解决无法解析表的问题(详细图解)
  • Docker部署kafka实操+Java中访问
  • 【KO】大厂常见问题
  • damn the jvm again(2)
  • DDIA第五章:无主复制(去中心化复制)详解
  • 华为发布AI推理新技术,降低对HBM内存依赖
  • 阿里云国际DDoS高防:添加网站配置指南
  • LabVIEW菜单操控
  • 【USRP】基于LabVIEW的BPSK、QPSK,文本,图片
  • 区块链技术原理(7)-安全问题
  • C++少儿编程(二十二)—条件结构
  • 云原生作业(nginx)
  • QT(概述、基础函数、界面类、信号和槽)
  • Linux 服务器,安装mqtt服务
  • Linux 系统下 VS Code 降级至 1.85 版本教程:通过历史版本网站解决兼容性问题
  • 从零开始手搓一个GPT大语言模型:从理论到实践的完整指南(一)
  • Linux性能监控
  • Qt Charts 深度解析与实战指南
  • 全面解析MySQL(5)——“索引、事务、JDBC”三大核心
  • AI不再停留在概念阶段,而是在各行业核心业务场景产生实际价值。随着大模型、边缘计算等技术的突破,AI应用将向实时化、自主化、普惠化方向深度演进。
  • 高性能web服务器Tomcat
  • 飞算 JavaAI -智慧城市项目实践:从交通协同到应急响应的全链路技术革新
  • 有趣的 npm 库 · json-server
  • Qt之QMetaEnum的简单使用(含源码和注释)
  • Windows 命令行:打开命令提示符界面
  • 【DL】浅层神经网络
  • 【实时Linux实战系列】实时环境监测系统架构设计