0

0

c# IAsyncResult 接口和 Task 的关系

煙雲

煙雲

发布时间:2026-01-03 00:21:26

|

101人浏览过

|

来源于php中文网

原创

Task未实现IAsyncResult接口,因二者分属APM与TAP两代异步模型,设计目标不兼容;但可通过Task.Factory.FromAsync封装APM方法为Task,或手动包装适配,推荐优先使用原生TAP方法。

c# iasyncresult 接口和 task 的关系

为什么 IAsyncResult 没有被 Task 直接继承或实现

IAsyncResult 是 .NET Framework 2.0 引入的异步编程模型(APM)核心接口,而 Task 是 .NET Framework 4.0 起引入的基于任务的异步模式(TAP)基石。二者属于不同代际的抽象,设计目标和使用方式不兼容:IAsyncResult 依赖 BeginXxx/EndXxx 成对方法 + 回调/轮询,Task 则围绕状态机、延续(continuation)、组合(.ContinueWithawait)构建。

所以 Task 类型本身**不实现 IAsyncResult 接口**,但提供了双向桥接能力:

  • Task.AsyncState 返回 IAsyncResult.AsyncState 对应的值(即传给 BeginXxx 的 state 参数)
  • Task.IsCompleted 对应 IAsyncResult.IsCompleted
  • Task.AsyncWaitHandle 可以暴露一个 WaitHandle,用于与旧式等待逻辑(如 WaitOne)交互

如何把 IAsyncResult 转成 Task

最常用、推荐的方式是使用 Task.Factory.FromAsync 方法族 —— 它不是“转换”,而是**封装 APM 调用为 Task 实例**,内部自动处理 BeginXxx 启动和 EndXxx 完成的衔接。

例如将 Stream.BeginRead 封装为 Task

var task = Task.Factory.FromAsync(
    stream.BeginRead,
    stream.EndRead,
    buffer,
    offset,
    count,
    null);

注意点:

  • 第四个参数(null)是 object state,会传给 BeginRead 并最终成为 task.AsyncState
  • 如果 EndXxx 方法有返回值(如 int),对应 FromAsync 返回 Task;无返回值则返回 Task
  • .NET 4.5+ 中更推荐直接使用已内置 TAP 方法(如 Stream.ReadAsync),避免手动桥接

Task 是否能当作 IAsyncResult 使用

不能直接当 IAsyncResult 传给要求该接口的 API(比如某些老框架的扩展点),因为 Task 没有实现该接口。但你可以用 Task 的属性模拟部分行为:

沙之丘企业网站程序3.5
沙之丘企业网站程序3.5

沙之丘企业网站程序是一个以asp.net(C#) 4.0 +access进行开发的企业网站源码。主要功能:1、产品、设备、新闻系统2、留言信息直接发邮件到相关部门3、所有链接都以一级目录显示更好的权重4、其他信息扩展,可以增加如:人事招聘,公司介绍,地图,联系我们等5、带有商品和设备的搜索功能6、模板动态化方便扩展模板7、简体繁体选择显示运行环境:windows 2003或者更高windows服务

下载
  • task.AsyncWaitHandle 提供一个 WaitHandle,可用于同步等待(WaitOne),但它**不是线程安全的重用句柄**,每次访问都可能返回新实例,且一旦任务完成就不再触发信号
  • task.AsyncState 是只读属性,值由构造时指定(如 new Task(..., state)),与 IAsyncResult.AsyncState 语义一致
  • task.IsCompletedIAsyncResult.IsCompleted 行为一致,但仅此而已 —— 缺少 AsyncWaitHandle 的稳定性和 CompletedSynchronously 等字段

强行适配需手动包装,例如:

public class TaskAsIAsyncResult : IAsyncResult
{
    private readonly Task _task;
    public object AsyncState => _task.AsyncState;
    public WaitHandle AsyncWaitHandle => _task.AsyncWaitHandle;
    public bool CompletedSynchronously => false;
    public bool IsCompleted => _task.IsCompleted;

    public TaskAsIAsyncResult(Task task) => _task = task;
}

但这种做法极少必要,且掩盖了模型差异,容易引发资源管理或生命周期问题。

实际开发中该选哪个

除非维护遗留代码或对接强制要求 IAsyncResult 的第三方库,否则一律优先使用 Taskasync/await

  • APM(IAsyncResult)已标记为“legacy”——文档明确建议迁移到 TAP
  • Task 支持取消(CancellationToken)、进度报告(IProgress)、组合(WhenAllWhenAny)、结构化异常传播,APM 几乎无法自然支持
  • 所有现代 .NET API(包括 HttpClientFileStreamSqlClient)都提供原生 XXXAsync 方法,返回 TaskValueTask

真正容易被忽略的是:有些老代码里混用 FromAsyncawait,结果在高并发下因 AsyncWaitHandle 创建开销或未正确释放句柄导致性能下降 —— 这类桥接应视为临时过渡,而非长期方案。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

434

2024.03.01

string转int
string转int

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

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

522

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

190

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

994

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

53

2025.10.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

150

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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