0

0

c# TaskCompletionSource 和 ManualResetEventSlim 的异同

月夜之吻

月夜之吻

发布时间:2026-01-14 22:10:52

|

194人浏览过

|

来源于php中文网

原创

TaskCompletionSource是手动控制的异步结果容器,用于将同步/回调逻辑转为可await的Task;ManualResetEventSlim是轻量级线程同步原语,用于多线程间信号通知,二者解决不同维度问题,不可互换。

c# taskcompletionsource 和 manualreseteventslim 的异同

TaskCompletionSource 适合封装异步操作结果

当你需要把一个同步或回调式逻辑“包装”成 Task,供 await 消费时,TaskCompletionSource 是首选。它不阻塞线程,只负责传递完成状态和结果,本质是“可手动控制的 Task 工厂”。

常见场景包括:模拟延迟、桥接事件(如 UI 控件点击)、封装第三方回调 API、实现自定义 awaitable。

  • SetResult()SetException()SetCanceled() 必须且只能调用一次,重复调用抛 InvalidOperationException
  • 构造时不传参数,默认使用 TaskCreationOptions.None;若需取消传播,可传 TaskCreationOptions.RunContinuationsAsynchronously
  • Task 属性是冷任务(cold task),不会自动执行,也不绑定线程
var tcs = new TaskCompletionSource();
// 在某个回调里:
tcs.SetResult(42);
// 后续可 await tcs.Task;

ManualResetEventSlim 用于线程间信号通知

ManualResetEventSlim 是轻量级同步原语,核心用途是让一个或多个线程等待某个条件成立(例如资源就绪、操作完成),然后被唤醒。它本质是“手动置位 + 多线程等待”的信号量,和 Task 体系无关。

典型场景:生产者-消费者模式中的空/满信号、等待后台初始化完成、协调多线程启动时机。

动软商城系统
动软商城系统

动软商城系统是一款优秀的网上商城系统,经营者只需要轻松的后台操作,就可以马上拥有功能强的网上销售系统,同时动软商城系统提供多样的营销手段帮助您成功打开网上销售市场。动软的模版界面机制,可以轻松的搭建出风格各异的界面,最大限度的满足经营者的要求,还拥有专业SEO优化系统,大大提高网页被搜索引擎抓取收录的几率。动软商城系统先进的流程控制技术全面促进进、销、存等系统的协同,支持企业数据整合和网络资源信息

下载
  • 支持自旋 + 内核切换双阶段,默认自旋 10 次,适合短等待;可通过构造函数调整 spinCount
  • Set() 置位后,所有等待线程立即唤醒,且保持置位状态直到显式调用 Reset()
  • 没有泛型参数,不携带数据;若需传递结果,得配合其他变量(注意加锁或用 Volatile.Read/Write
var mres = new ManualResetEventSlim(false);
// 线程 A:
Task.Run(() => {
    Thread.Sleep(1000);
    mres.Set(); // 通知完成
});
// 线程 B:
mres.Wait(); // 阻塞直到 Set()

别把两者当替代品用

它们解决的是不同维度的问题:TaskCompletionSource 是异步编程模型的“结果容器”,面向 async/await 流;ManualResetEventSlim 是同步协调工具,面向线程阻塞与唤醒。强行混用容易引入死锁或性能陷阱。

  • async 方法里调用 mres.Wait() 会阻塞当前线程,可能拖垮线程池;应改用 mres.WaitAsync()(.NET 6+)或包装成 Task 手动调度
  • TaskCompletionSource 实现“等待信号”功能,虽可行但冗余——它不提供等待能力,还得额外配 Task.Delay 或轮询,不如直接用 WaitHandleChannel
  • ManualResetEventSlim 无法参与 await usingValueTask 优化;而 TaskCompletionSourceTask 可以被 ValueTask 封装复用(需谨慎)

容易忽略的细节

真正出问题的地方往往藏在边界行为里:

  • TaskCompletionSource 构造时若传入 TaskCreationOptions.RunContinuationsAsynchronously,后续 await 的 continuation 一定在 ThreadPool 线程执行;否则可能在调用 SetXXX 的同一线程同步执行(影响 UI 响应或造成溢出)
  • ManualResetEventSlimWait() 在 .NET Core/.NET 5+ 中支持取消令牌,但 CancellationToken 触发时抛 OperationCanceledException,不是静默返回;而 WaitAsync() 返回 Task,更符合 async 场景
  • 两者都不自带超时逻辑:TaskCompletionSource 要靠外部 Task.Delay().ContinueWith()TimeoutAfter() 扩展;ManualResetEventSlim.Wait()WaitAsync() 都有带 timeout 的重载,但单位是毫秒,不是 TimeSpan(易写错)

相关专题

更多
c++中volatile关键字的作用
c++中volatile关键字的作用

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

67

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

388

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

571

2023.08.10

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

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

480

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

244

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

342

2025.11.17

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

php与html混编教程大全
php与html混编教程大全

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

14

2026.01.13

热门下载

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

精品课程

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

共58课时 | 3.6万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.6万人学习

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

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