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

相关文章:

  • 代码随想录算法训练营四十二天|单调栈part02
  • 【Activiti】要点初探
  • 迈向具身智体人工智能:LLM 和 VLM 驱动的机器人自主性和交互性
  • 11-docker单机版的容器编排工具docker-compose基本使用
  • Qt中定时器介绍和使用
  • 文字转语音 edge_tts
  • Spring IoC实现原理详解
  • [激光原理与应用-251]:理论 - 几何光学 - 长焦与短焦的比较
  • 晶片与电路板的桥梁-封装
  • 回归预测 | Matlab实现CNN-BiLSTM-self-Attention多变量回归预测
  • 外卖投诉:差评转复购的3步攻略
  • DOM2 Style的隐藏武器:getComputedStyle()的使用指南
  • idea git commit特别慢,cpu100%
  • dag实现案例 02、实现简易版dag调度系统(基于01之上升级)
  • GeoScene 空间大数据产品使用入门(6)进阶模型
  • 软考备考(三)
  • jupyter notebook中查看kernel对应环境的解决方案
  • RK3568 Linux驱动学习——Linux LED驱动开发
  • 安全合规5--终端安全检测和防御技术
  • 【1】Transformers快速入门:自然语言处理(NLP)是啥?
  • 肖臻《区块链技术与应用》第九讲:比特币交易的“智能”核心:深入解析脚本语言Script
  • 常见的设计模式(2)单例模式
  • TDengine 初体验
  • Flink Python API 提交 Socket 数据源的 WordCount 作业
  • TDengine 可观测性最佳实践
  • 荣耀手机无法连接win11电脑,错误消息:“无法在此设备上加载驱动程序 (hn_usbccgpfilter.sys)。”解决方案
  • Flink运行时的实现细节
  • 嵌入式Linux进程管理面试题大全(含详细解析)
  • 基于热成像摄像头检测蚊子的可行性研究
  • iOS 签名证书全生命周期实战,从开发到上架的多阶段应用