利用 TaskCompletionSource 在 SuperSocket 中实现跨模块异步处理客户端消息

在使用 SuperSocket 构建 TCP 服务时,我们经常会遇到这样的需求:

  • 服务端接收到客户端数据后,需要将数据交给其他模块处理
  • 处理完成后再将结果返回给调用模块或客户端
  • 希望调用模块能够异步等待处理结果,而不是阻塞线程

本文将通过 TaskCompletionSource 来实现这一场景,并结合 SuperSocket 的异步回调机制,讲解完整实现方法。


1️⃣ TaskCompletionSource 基础语法

TaskCompletionSource<T>(简称 TCS)是 .NET 中用于手动控制 Task 完成时机的工具。

1.1 基本概念

  • Task:异步操作的表示,通常由方法内部执行完成
  • TaskCompletionSource:你可以手动控制 Task 何时完成,以及完成结果是什么
var tcs = new TaskCompletionSource<int>();
Task<int> task = tcs.Task;// 模拟异步事件
Task.Run(async () =>
{await Task.Delay(1000);   // 模拟耗时操作tcs.SetResult(42);        // 手动完成 Task 并返回结果
});int result = await task;
Console.WriteLine(result);    // 输出 42

核心思想:TaskCompletionSource 就像一个“空盒子”,你自己决定什么时候放入结果并“打开盒子”。


1.2 TCS 常用方法

方法功能
SetResult(T result)设置 Task 成功完成并返回结果
TrySetResult(T result)安全写法,如果 Task 已完成不会抛异常
SetException(Exception ex)设置 Task 异常完成
SetCanceled()取消 Task

2️⃣ 在 SuperSocket 中使用 TCS

SuperSocket 的核心是事件驱动,客户端数据到达时会触发 UsePackageHandler 回调。我们可以利用 TCS,将“事件”转换为“可 await 的 Task”,实现异步等待消息。


2.1 定义等待方法

在服务端或调用模块中定义:

private TaskCompletionSource<int> _tcs;public Task<int> WaitForNextPackageAsync()
{_tcs = new TaskCompletionSource<int>();return _tcs.Task; // 返回可 await 的 Task
}
  • 外部模块调用 await WaitForNextPackageAsync() 时,会挂起等待
  • 直到 _tcs.SetResult(result) 被触发

2.2 接收客户端消息并触发 TCS

public event Func<StringPackageInfo, Task<int>> OnPackageReceived;private async ValueTask HandlePackageAsync(IAppSession session, StringPackageInfo package)
{int result = 0;// 调用外部模块处理消息if (OnPackageReceived != null){result = await OnPackageReceived.Invoke(package);}// 完成 TaskCompletionSource,将结果返回给等待方_tcs?.TrySetResult(result);// 同时可以给客户端发送响应await session.SendAsync(Encoding.UTF8.GetBytes(result.ToString() + "\r\n"));
}

这里实现了 消息接收与处理逻辑解耦

  • SuperSocket 只负责接收消息
  • 外部模块处理业务逻辑
  • 调用模块异步等待处理结果

2.3 外部模块处理逻辑示例

mainWindow.OnPackageReceived += async (package) =>
{int result = 0;switch (package.Key.ToUpper()){case "ADD":result = package.Parameters.Select(int.Parse).Sum();break;case "SUB":result = package.Parameters.Select(int.Parse).Aggregate((x, y) => x - y);break;case "MULT":result = package.Parameters.Select(int.Parse).Aggregate((x, y) => x * y);break;}return result; // 返回给 TaskCompletionSource
};

2.4 调用模块等待结果

int result = await mainWindow.WaitForNextPackageAsync();
Console.WriteLine($"处理结果: {result}");
  • 外部模块就像同步等待一样获得了处理结果
  • 实际上整个流程是 异步、非阻塞

3️⃣ 支持多客户端或多条命令

如果有多个客户端或希望同时处理多条消息,可以使用 队列管理 TCS

private ConcurrentQueue<TaskCompletionSource<int>> _queue = new();public Task<int> WaitNextAsync()
{var tcs = new TaskCompletionSource<int>();_queue.Enqueue(tcs);return tcs.Task;
}private async ValueTask HandlePackageAsync(IAppSession session, StringPackageInfo package)
{int result = CalculateResult(package);if (_queue.TryDequeue(out var tcs))tcs.TrySetResult(result);await session.SendAsync(Encoding.UTF8.GetBytes(result.ToString() + "\r\n"));
}
  • 每条消息对应一个 TCS
  • 保证多客户端/多命令都能异步等待结果

4️⃣ 总结

把回调变成了异步等待,这个真的是太酷啦~~~~~~~

通过 TaskCompletionSource,我们可以:

  1. 将事件驱动转为可 await 的异步操作
  2. 实现跨模块异步处理客户端消息
  3. 保持服务端与业务逻辑解耦
  4. 同时支持客户端响应和模块异步等待

核心模式:
HandlePackageAsync 触发 → 外部模块处理 → TaskCompletionSource.SetResult → 调用模块 await 获取结果

这种模式非常适合 SuperSocket、SignalR、WebSocket 等异步消息驱动场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921177.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921177.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921177.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《IC验证必看|semaphore与mailbox的核心区别》

月薪30K验证工程师必答&#xff1a;SystemVerilog中semaphore与mailbox的核心区别&#xff0c;及必须用semaphore的场景深度解析 在验证工程师的技能体系里&#xff0c;线程同步与资源管控是区分“基础会用”&#xff08;20K水平&#xff09;和“精通工程化”&#xff08;30K水…

Spring线程池ThreadPoolTaskExecutor‌详解

ThreadPoolTaskExecutor‌写法Bean(name "taskExecutor") public ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setCorePoolSize(8); // 8核CPU服务器建议值executor.setMaxPoolSize(…

Unity之安装教学

UnityHub下载 下载官网地址&#xff1a;Unity Hub下载地址 打开网址右上角&#xff0c;登录/注册账号 登录完毕后&#xff0c;点击下载 安装Unity Hub 双击傻瓜式安装 安装完成 启动UnityHub 双击启动 左上角设置 设置中文 左上角登录账号 添加免费许可证 设置-许可证-添加 安装…

Redis 集群模式与高可用机制

最近在准备面试&#xff0c;正把平时积累的笔记、项目中遇到的问题与解决方案、对核心原理的理解&#xff0c;以及高频业务场景的应对策略系统梳理一遍&#xff0c;既能加深记忆&#xff0c;也能让知识体系更扎实&#xff0c;供大家参考&#xff0c;欢迎讨论。在分布式环境下&a…

Flutter + Web:深度解析双向通信的混合应用开发实践

Flutter Web&#xff1a;深度解析双向通信的混合应用开发实践 前言 在当今快速发展的移动应用开发领域&#xff0c;开发者们始终在寻求一种能够平衡开发效率、跨平台能力和用户体验的完美方案。原生开发性能卓越&#xff0c;但双平台&#xff08;iOS/Android&#xff09;开发…

如何查看Linux系统中文件夹或文件的大小

在日常运维和开发工作中&#xff0c;了解文件夹和文件占用的磁盘空间是非常重要的。尤其是当你在服务器上部署应用&#xff08;如 Jenkins&#xff09;时&#xff0c;合理监控磁盘使用情况可以避免磁盘空间不足导致的各种问题。在 Linux 系统中&#xff0c;我们可以使用一些简单…

豪华酒店品牌自营APP差异对比分析到产品重构

一、万豪国际集团旗下豪华酒店品牌及统一APP 万豪旗下奢华品牌均整合于 「万豪旅享家(Marriott Bonvoy)」APP,会员可通过该平台预订、管理积分及享受跨品牌服务。以下为核心豪华品牌: 1. 经典奢华品牌 丽思卡尔顿酒店(The Ritz-Carlton) 定位:顶级奢华,以管家服务、历…

ESLint 相关

no-unused-vars 等常见报错提醒关闭 1. no-unused-vars 报错示例&#xff1a; useMemo is defined but never used no-unused-vars解决方式 方法一&#xff1a;局部禁用某一行 // eslint-disable-next-line no-unused-vars const result useMemo(() > {}, []);方法二&…

1分钟生成爆款相声对话视频!Coze智能体工作流详细搭建教程,小白也能轻松上手

最近看到一个账号&#xff0c;用AI将传统相声对话做成趣味短视频&#xff0c;单条播放量轻松破百万。这种视 频看似复杂&#xff0c;其实用Coze智能体工作流1分钟就能搞定&#xff0c;完全不需要剪辑基础。工作流功能 用Coze一键生成爆款相声对话视频&#xff0c;无需剪辑直接发…

pinia状态管理工具

pinia状态管理工具Pinia 是 Vue.js 官方推荐的新一代状态管理库&#xff0c;可以看作是 Vuex 的替代品。1. 什么是 Pinia&#xff1f; Pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态。由 Vue.js 核心团队维护&#xff0c;并且对 TypeScript 有着极其…

【初始web3】什么是web3

前言你是否还记得&#xff0c;曾经在社交媒体上发布精彩内容&#xff0c;平台却随意封禁你的账号&#xff1f;你是否曾疑惑&#xff0c;为什么你创造的数据价值亿万&#xff0c;而你自己却一无所获&#xff1f;这&#xff0c;就是Web2时代的痛。而Web3的到来&#xff0c;正试图…

构建下一代互联网:解码Web3、区块链、协议与云计算的协同演进

我们正站在互联网历史性变革的门口。从只能读取信息的Web1&#xff0c;到可以读写、高度中心化的Web2&#xff0c;我们即将迈入一个价值可以直接传递的Web3时代。这个新时代并非由单一技术驱动&#xff0c;而是由区块链、去中心化协议和云计算等一系列技术的融合与协同所构建。…

小迪安全v2023学习笔记(七十六讲)—— Fuzz模糊测试口令爆破目录爆破参数爆破Payload爆破

文章目录前记WEB攻防——第七十六天Fuzz模糊测试篇&JS算法口令&隐藏参数&盲Payload&未知文件目录Fuzz知识含义Fuzz的核心思想Fuzz应用场景Fuzz应用Fuzz字典项目Fuzz技术 - 用户口令-常规&模块&JS插件常规模块JS插件JsEncrypterBurpCryptoFuzz技术 - 目…

在windows server 2022搭建gitlab……但是失败了

在windows server 2022搭建gitlab……但是失败了1. 前言2. 安装ubuntu环境2. 安装docker3. 映射3.1 端口映射3.2 路径映射1. 前言 上一篇&#xff1a;在windows本地机搭建gitlab 本来按理来说没必要另起一篇&#xff0c;但是没想到&#xff0c;在新机器的windows server 2022…

蓝桥杯算法之基础知识(4)

目录 Ⅰ.sorted排序 Ⅱ.排序具体的方法 &#xff08;1&#xff09;sort的神方法&#xff08;注意是sort&#xff09; &#xff08;2&#xff09;sorted的神方法&#xff08;注意这里是sorted&#xff09; 常见场景 1. 单关键字排序 2. 多关键字排序 3.按倒序字符串排序&#xf…

GOFLY开源客服系统-处理gin框架下的session中间件

了解更多&#xff0c;搜索:"程序员老狼" 在当今数字化时代&#xff0c;在线客服系统已成为企业与客户沟通的重要桥梁。作为GOFLY客服系统的开发者&#xff0c;我今天要分享我们如何在系统中实现安全可靠的会话管理机制——这是保障用户数据安全的核心技术。 为什么…

Burp Suite 插件 | 提供强大的框架自动化安全扫描功能。目前支持1000+POC、支持动态加载POC、指定框架扫描。

工具介绍 Rinte 是一款专为渗透测试人员设计的 Burp Suite 插件&#xff0c;提供强大的自动化安全扫描功能。该插件集成了框架检测、漏洞扫描和敏感路径扫描等多种功能&#xff0c;帮助安全研究人员快速识别目标系统的安全漏洞。支持1000框架POC、支持动态加载POC、指定框架扫描…

记录测试环境hertzbeat压测cpu高,oom问题排查。jvm,mat,visulavm

记录测试环境hertzbeat压测cpu高&#xff0c;oom问题排查。jvm&#xff0c;mat&#xff0c;visulavm 一&#xff0c;问题背景 运维平台&#xff0c;采用hertzbeat开源代码进行采集。对单个设备连接&#xff0c;采集9个指标。目前hertzbeat对1个设备连接&#xff0c;下发9次单独…

基于 CC-Link IE FB 转 DeviceNet 技术的三菱 PLC 与发那科机器人在汽车涂装线的精准喷涂联动

案例背景在汽车制造行业&#xff0c;生产线的高效协同是提高生产效率和产品质量的关键。某汽车制造企业的车身焊接车间采用了基于 CC-Link IE FB 主站的三菱 Q 系列 PLC&#xff0c;凭借其强大的功能和稳定的性能&#xff0c;对焊接机器人等设备进行精准控制。而在涂装车间&…

极空间打造 “超级中枢”,从书签笔记到聊天分享,一键全搞定!

「NAS、键盘、路由器年轻就要多折腾&#xff0c;我是爱折腾的熊猫&#xff0c;今天又给大家分享最近折腾的内容了&#xff0c;关注是对我最大的支持&#xff0c;阿里嘎多」引言书签项目熊猫介绍过不少啦&#xff0c;但今天要介绍的这个项目&#xff0c;大不一样。平常的书签&am…