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

.NET 中的异步编程模型

同步和异步的关键区别:同步方法会阻塞线程,而异步方法在 await 时释放线程,让它可以处理其他任务。

await 操作符的作用:当遇到 await 时,当前方法会暂停,线程返回线程池,等待任务完成后再继续执行。

异步方法不会增快程序处理的速度,只会提高处理程序的数量。

异步方法通常用于那些耗时较长的操作,避免阻塞主线程,提高系统响应速度。


ERP 中适合用异步方法的场景

  • 耗时操作:如批量数据导入 / 导出、复杂报表生成、大数据分析(如销售趋势预测)。
  • 非即时性需求:如夜间自动备份数据、定期发送供应商对账邮件、批量更新商品库存。
  • 高并发场景:当多个用户同时触发耗时操作时,异步方法可避免系统因压力过大而崩溃。

 这些操作如果用同步方法,用户可能需要长时间等待,影响体验。而异步的话,可以让用户继续操作其他功能,后台处理这些任务。

异步方法的好处:提高用户体验,系统资源利用率更高,不会因为一个耗时操作影响整个系统的性能。

异步的实现方式:使用队列、回调函数或者消息机制。


在 ERP 系统中,即使需要等待操作结果,也可能选择异步方法而非同步方法,主要基于以下原因:

1. 避免线程阻塞,提升系统吞吐量

2. 改善用户体验,等待期间系统保持响应

3. 与其他异步组件集成

4. 资源管理更灵活

  • 同步方法:长时间占用线程资源,可能导致资源浪费。
  • 异步方法:可结合超时控制、取消令牌(CancellationToken)等机制,更精细地管理资源。

 


异步方法(优化做法)
  • 操作流程

    1. 会计点击 “生成 6 月财务总览报表” 按钮后,系统立即返回提示:“报表正在生成中,您可以继续其他操作。”
    2. 后台异步处理
      • 系统将报表生成任务放入 “任务队列”,并启动独立的线程或进程处理数据查询和计算。
      • 此时,用户可以继续在 ERP 中处理采购订单、审核报销单等其他任务,界面操作完全不受影响。
    3. 当报表生成完成后,系统通过弹窗、短信或邮件通知会计:“6 月财务报表已生成,可随时查看。”
  • 优势

    • 用户体验提升:无需等待耗时任务完成,可并行处理多项工作。
    • 系统效率更高:资源不会被单一任务阻塞,多个任务可同时推进(如一边生成报表,一边处理订单)。


 

Task.Delay 是一个异步方法,它会让当前的执行流程暂停指定的时间,同时不会阻塞线程。await Task.Delay(5000) 会让程序暂停 5 秒钟,在这期间,线程可以去处理其他任务,而不是一直处于阻塞状态。

  • 当代码执行到 await Task.Delay(5000) 时:
    1. 暂停当前方法:方法执行流在此处暂停,但不阻塞线程
    2. 线程返回线程池:当前线程(可能来自线程池)被释放,可用于处理其他任务。
    3. 后台调度等待Task.Delay 会注册一个定时器,5 秒后通知系统继续执行后续代码。
  • 等待完成后,系统从线程池获取一个可用线程,继续执行 await 后的代码。

设计目的:避免无效检查和资源浪费

  • 场景合理性:账套恢复(如数据库还原、服务重启)属于耗时操作,不可能瞬间完成。直接检查状态会得到 “未开始” 或 “进行中” 的结果,导致无效判断。
  • 性能优化:通过定时等待(而非高频循环),减少对数据库或服务的无效查询,降低资源消耗。
  • 兼容性考虑:远程服务(如 WCF、API)可能存在响应延迟,等待时间为操作预留了执行窗口。

使用回调函数替代轮询

场景:账套恢复完成后自动触发后续操作,无需手动检查状态。
实现方式
  • 步骤 1:定义回调委托。
  • 步骤 2:在异步方法中注册回调。
  • 步骤 3:状态变化时(如恢复成功)触发回调。
// 定义回调委托
public delegate void RecoveryStatusChangedHandler(string packageNo, int status);public class PresentiveAccountSetMaintainer
{// 事件:状态变化时触发public event RecoveryStatusChangedHandler OnRecoveryStatusChanged;public async Task StartRecoveryAsync(int reservedAsId, int adminUserSn, string packageNo){using (var client = AccServiceFactory.GetErpBackupEngineAdapter(AppSettings.ScmType)){// 启动恢复操作client.RecoveryErpProxy(reservedAsId, adminUserSn, true, packageNo);// 异步等待恢复完成await MonitorRecoveryStatusAsync(packageNo, TimeSpan.FromSeconds(30));}}private async Task MonitorRecoveryStatusAsync(string packageNo, TimeSpan timeout){var startTime = DateTime.Now;while (DateTime.Now - startTime < timeout){var status = CheckRecoveryStatus(packageNo);// 触发状态变化事件OnRecoveryStatusChanged?.Invoke(packageNo, status);// 如果恢复成功,退出循环if (status == 2){return;}// 如果正在恢复,等待一段时间后继续检查if (status == 3){await Task.Delay(5000);continue;}// 如果恢复失败,抛出异常if (status == 1){throw new Exception($"账套恢复失败,包编号:{packageNo}");}}// 超时处理throw new TimeoutException($"账套恢复超时,包编号:{packageNo}");}
}
var maintainer = new PresentiveAccountSetMaintainer();// 注册回调
maintainer.OnRecoveryStatusChanged += (packageNo, status) =>
{switch (status){case 2: // 恢复成功Console.WriteLine($"账套 {packageNo} 恢复成功!");// 自动触发后续操作(如数据校验)ValidateAccountData(packageNo);break;case 3: // 正在恢复Console.WriteLine($"账套 {packageNo} 正在恢复中...");break;case 1: // 恢复失败Console.WriteLine($"账套 {packageNo} 恢复失败!");break;}
};// 启动恢复
await maintainer.StartRecoveryAsync(reservedAsId, adminUserSn, packageNo);

http://www.xdnf.cn/news/995383.html

相关文章:

  • [电赛]MSPM0G3507学习笔记(二) GPIO:led与按键(流水灯、呼吸灯,短按长按与双击,ui预览)
  • 基于OpenCV和深度学习实现图像风格迁移
  • VR 地震安全演练:“透视” 地震,筑牢企业安全新护盾​
  • 16层混压PCB的精密重构:高频基板局部化的黄金法则
  • 【Go-补充】实现动态数组:深入理解 slice 与自定义实现
  • 机器学习 [白板推导](六)[核方法、指数族分布]
  • 【WebSocket】WebSocket架构重构:从分散管理到统一连接的实战经验
  • 新零售视域下实体与虚拟店融合的技术逻辑与商业模式创新——基于开源AI智能名片与链动2+1模式的S2B2C生态构建
  • C#事件基础模型代码
  • 【技术追踪】MMFusion:用于食管癌淋巴结转移诊断的多模态扩散模型(MICCAI-2024)
  • Linux部署bmc TrueSight 监控agent步骤
  • Java学习笔记之:初识nginx
  • js判断手机操作系统(ios、安卓、华为)
  • 分享在日常开发中常用的ES6知识点【面试常考】
  • “储能+热泵+AI”三维驱动,美的能源定义能源科技新未来
  • 【深度解读】混合架构数据保护实战
  • 从零搭建智能家居:香橙派+HomeAssistant实战指南
  • LlamaIndex 工作流 上下文状态和流式传输事件
  • SpringBoot+Junit在IDEA中实现查询数据库的单元测试
  • 代码训练LeetCode(32)Z字形变换
  • chrome138版本及以上el-input的textarea输入问题
  • 鸿蒙北向应用开发:新增ts文件出现的问题
  • 【狂飙AGI】第1课:大模型概述
  • QT+VTK 中QWidget与QVTKOpenGLNativeWidget的使用
  • python打卡第52天
  • 如何从 Ansys SpaceClaim 模型中提取 CAD 数据,该模型是在我计算机上安装的未来版本中创建的?
  • Kafka问题排查笔记
  • 全局搜索正则表达式grep
  • 用volatile修饰数组代表什么意思,Java
  • physicsnemo开源程序是开源深度学习框架,用于使用最先进的 Physics-ML 方法构建、训练和微调深度学习模型