0

0

c# 异步编程模型 APM EAP TAP 的区别

月夜之吻

月夜之吻

发布时间:2025-12-27 06:25:33

|

907人浏览过

|

来源于php中文网

原创

APM 是 .NET 早期基于 IAsyncResult 的异步模式,现已被淘汰,新项目完全不该使用;EAP 主要用于旧 UI 框架,已标记过时;TAP 是当前唯一推荐的标准异步模式,全面支持 async/await、取消、异常和组合操作。

c# 异步编程模型 apm eap tap 的区别

APM 是什么,现在还该用吗

APM(Asynchronous Programming Model)是 .NET 早期的异步模式,基于 IAsyncResult 接口,靠 BeginXXX/EndXXX 成对方法实现。比如 FileStream.BeginReadFileStream.EndRead

它的问题很实际:回调嵌套深、异常处理分散、取消逻辑难统一、资源释放容易出错。.NET Core 2.0+ 已不再为新 API 添加 APM 支持,新项目完全不该选用 APM

  • 不支持 async/await 语法,无法自然融入现代 C# 异步流
  • EndXXX 必须调用,否则可能丢失异常或阻塞资源(如未调用 EndRead 可能导致句柄泄漏)
  • 没有内置取消机制,需手动传入 CancellationToken 并在回调中检查

EAP 在 WinForms/WPF 中为什么还能见到

EAP(Event-based Asynchronous Pattern)以 MethodNameAsync + MethodNameCompleted 事件形式存在,典型如 WebClient.DownloadStringAsyncDownloadStringCompleted 事件。

它主要服务于 UI 框架的线程模型,自动把完成回调封送到 UI 线程(通过 SynchronizationContext),所以老式 WinForms/WPF 代码里还能看到。但它的设计本质是“为 UI 而妥协”,不是通用异步抽象。

  • 不返回 Task,无法用 await,也不能参与 Task.WhenAll 等组合操作
  • 错误和结果都打包在 AsyncCompletedEventArgsErrorResult 属性里,类型擦除严重(Resultobject
  • .NET 5+ 已标记多数 EAP 方法为 [Obsolete],比如 SmtpClient.SendAsync

TAP 是唯一推荐的现代异步模式

TAP(Task-based Asynchronous Pattern)是当前 C# 异步的标准,所有新 API 都遵循它:方法名以 Async 结尾,返回 TaskTask,支持 await,原生集成取消、进度报告和同步上下文。

Dreamphilic
Dreamphilic

一个基于web的工具,为用户提供AI生成的内容。

下载

它不是“另一种选择”,而是事实标准。哪怕你封装一个旧 APM 方法,也该用 TaskFactory.FromAsync 转成 TAP;调用 EAP 方法,也该用 TaskCompletionSource 包一层。

  • async 方法体内可直接 await 任何 TAP 方法,包括你自己写的 async Task GetDataAsync()
  • 统一用 CancellationToken 控制取消,且绝大多数 TAP 方法都提供带 token 的重载(如 HttpClient.GetAsync(uri, token)
  • 异常会原样抛出(非包装进 AggregateException),调试体验好
public async Task FetchDataAsync(string url, CancellationToken ct = default)
{
    using var client = new HttpClient();
    var response = await client.GetAsync(url, ct); // 自动响应取消
    return await response.Content.ReadAsStringAsync(ct);
}

混用三种模式时最容易踩的坑

真实项目常要对接老代码或第三方库,可能同时遇到三种模式。这时最危险的操作是“假装它们等价”——比如把 BeginInvoke 回调里直接调 EndInvoke,却不考虑同步上下文;或给 EAP 事件 handler 加 async void 导致异常无法捕获。

  • 不要在 EAP 的 Completed 事件处理器里写 async void —— 改用 async Task 并手动调用 await 后续逻辑,否则异常会直接崩掉进程
  • Task.Factory.FromAsync 包装 APM 时,必须确保 EndXXX 被调用 —— 它内部已帮你做了,但自定义包装时容易漏
  • 从 TAP 切回同步调用(如 task.Resulttask.Wait())极易引发死锁,尤其在有 SynchronizationContext 的环境(WinForms/WPF/ASP.NET MVC)

异步模型的差异不在语法糖,而在控制流所有权和错误传播路径。选错起点,后面每一步都在补洞。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

311

2023.08.02

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.10.25

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6029

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

778

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1044

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1064

2024.03.01

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

172

2023.11.23

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

25

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 2.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

Sass 教程
Sass 教程

共14课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号