重庆网站排名,网站模块是什么,免费asp网站程序下载,网站做宣传同步和异步的关键区别#xff1a;同步方法会阻塞线程#xff0c;而异步方法在 await 时释放线程#xff0c;让它可以处理其他任务。
await 操作符的作用#xff1a;当遇到 await 时#xff0c;当前方法会暂停#xff0c;线程返回线程池#xff0c;等待任务完成后再继续…
同步和异步的关键区别同步方法会阻塞线程而异步方法在 await 时释放线程让它可以处理其他任务。
await 操作符的作用当遇到 await 时当前方法会暂停线程返回线程池等待任务完成后再继续执行。
异步方法不会增快程序处理的速度只会提高处理程序的数量。
异步方法通常用于那些耗时较长的操作避免阻塞主线程提高系统响应速度。 ERP 中适合用异步方法的场景
耗时操作如批量数据导入 / 导出、复杂报表生成、大数据分析如销售趋势预测。非即时性需求如夜间自动备份数据、定期发送供应商对账邮件、批量更新商品库存。高并发场景当多个用户同时触发耗时操作时异步方法可避免系统因压力过大而崩溃。 这些操作如果用同步方法用户可能需要长时间等待影响体验。而异步的话可以让用户继续操作其他功能后台处理这些任务。
异步方法的好处提高用户体验系统资源利用率更高不会因为一个耗时操作影响整个系统的性能。
异步的实现方式使用队列、回调函数或者消息机制。 在 ERP 系统中即使需要等待操作结果也可能选择异步方法而非同步方法主要基于以下原因
1. 避免线程阻塞提升系统吞吐量
2. 改善用户体验等待期间系统保持响应
3. 与其他异步组件集成 4. 资源管理更灵活
同步方法长时间占用线程资源可能导致资源浪费。异步方法可结合超时控制、取消令牌CancellationToken等机制更精细地管理资源。 异步方法优化做法 操作流程 会计点击 “生成 6 月财务总览报表” 按钮后系统立即返回提示“报表正在生成中您可以继续其他操作。”后台异步处理 系统将报表生成任务放入 “任务队列”并启动独立的线程或进程处理数据查询和计算。此时用户可以继续在 ERP 中处理采购订单、审核报销单等其他任务界面操作完全不受影响。 当报表生成完成后系统通过弹窗、短信或邮件通知会计“6 月财务报表已生成可随时查看。” 优势 用户体验提升无需等待耗时任务完成可并行处理多项工作。系统效率更高资源不会被单一任务阻塞多个任务可同时推进如一边生成报表一边处理订单。 Task.Delay 是一个异步方法它会让当前的执行流程暂停指定的时间同时不会阻塞线程。await Task.Delay(5000) 会让程序暂停 5 秒钟在这期间线程可以去处理其他任务而不是一直处于阻塞状态。
当代码执行到 await Task.Delay(5000) 时 暂停当前方法方法执行流在此处暂停但不阻塞线程。线程返回线程池当前线程可能来自线程池被释放可用于处理其他任务。后台调度等待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);