0

0

C# TaskCompletionSource的用法 - 将回调模式转换为async/await

煙雲

煙雲

发布时间:2025-12-08 17:57:14

|

950人浏览过

|

来源于php中文网

原创

TaskCompletionSource是C#中将回调式异步操作包装为可await的Task的核心工具,不执行异步逻辑,仅手动控制Task完成状态(成功/失败/取消),适用于桥接事件、回调、IAsyncResult等非Task异步模型。

c# taskcompletionsource<t>的用法 - 将回调模式转换为async/aw<a   style=ait - php中文网"/>

TaskCompletionSource 是 C# 中把“回调式异步操作”包装成 Task、从而支持 await 的核心工具。它不执行任何异步逻辑,只负责手动控制一个 Task 的完成状态(成功、失败、取消)。

什么时候需要 TaskCompletionSource

常见于以下场景:

  • 调用老式 API(比如基于事件或回调的 SDK,如 WebSocket.OnMessage、HttpClient.SendAsync 的旧封装)
  • 需要自己定义异步契约,比如实现超时控制、延迟触发、信号等待(类似 ManualResetEventSlim + Task)
  • 桥接非 Task 的异步模型(如 Begin/End 模式、IAsyncResult)

基本用法:三步走

以“监听一次 WebSocket 消息”为例:

var tcs = new TaskCompletionSource();// 1. 订阅回调(比如 WebSocket 收到消息时触发)
webSocket.OnMessage += (msg) =>
{
// 2. 成功完成 Task,值为 msg
tcs.TrySetResult(msg);
};// 3. 返回可 await 的 Task
return tcs.Task;

调用方就可以这样写:

string msg = await WaitForNextMessage(); // 干净、线性、可异常传播

务必注意 TrySetXXX 的安全性

TrySetResult/TrySetException/TrySetCanceled 是线程安全且幂等的 —— 多次调用只生效第一次,不会抛异常。推荐始终用 TrySet* 系列,而不是 Set*

Axiom
Axiom

Axiom是一个浏览器扩展,用于自动化重复任务和web抓取。

下载

常见错误:

  • 重复调用 SetResult → 抛 InvalidOperationException
  • 在 Task 已完成后再设置 → 同样崩溃
  • 忘记处理异常或取消路径 → Task 永远不完成(死等)

配合 CancellationToken 实现可取消等待

不能直接取消 TaskCompletionSource 本身,但可以监听 token 并主动取消:

var tcs = new TaskCompletionSource();using var registration = cancellationToken.Register(() =>
{
tcs.TrySetCanceled(); // 注意:传入 token 可选,但建议显式传入
});// ... 后续回调中调用 TrySetResult 或 TrySetException

这样 await tcs.Task 就能响应 cancellationToken,抛出 OperationCanceledException

基本上就这些。它不复杂,但容易忽略线程安全和完成唯一性 —— 用好 TrySet* 和及时清理资源(比如注销事件),就能稳稳把回调转成 async/await。

相关专题

更多
登录token无效
登录token无效

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

6107

2023.09.14

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

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

813

2023.09.14

token怎么获取
token怎么获取

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

1064

2023.12.21

token什么意思
token什么意思

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

1283

2024.03.01

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Golang WebSocket与实时通信开发
Golang WebSocket与实时通信开发

本专题系统讲解 Golang 在 WebSocket 开发中的应用,涵盖 WebSocket 协议、连接管理、消息推送、心跳机制、群聊功能与广播系统的实现。通过构建实际的聊天应用或实时数据推送系统,帮助开发者掌握 如何使用 Golang 构建高效、可靠的实时通信系统,提高并发处理与系统的可扩展性。

20

2025.12.22

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

44

2026.01.19

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

53

2026.01.21

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
swoole入门物联网开发与实战
swoole入门物联网开发与实战

共15课时 | 1.2万人学习

swoole项目实战(第二季)
swoole项目实战(第二季)

共15课时 | 1.2万人学习

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

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