async...await在tcp通讯中的正确用法
2024-10-18 14:32:14
- 引言
编程能力在不断的总结中进步以及成长,最近的半年里,对之前的开源项目代码进行回归,在重构的过程中进行了很多思考,很多次都想放弃重构,毕竟一个已经在使用的项目,重构基础代码就相当于重新开发了,不过最终还是下定了决心,毕竟重构就是一个成长过程,要想进步,就要不断的发现原有代码的不足,使用新的思维去优化原来的东西,在重构的过程中,针对tcp网络通讯,我有了新的思路。
- 简介
无论是网上的tcp示例或者书本的示例,只要是异步方式,读写基本都是分离的,也就是说如果想通过tcp去和服务端进行数据交互,你在A方法发送了指令,只能在B方法接收并进行处理,这种发送与接收数据不在同一个方法内,严重干扰了代码的顺序执行逻辑,我们需要将发送前和接收后的代码写在不同的地方,而现在,我们可以卸载一起。例如:
long fileId = 1001;
// 通过tcp发送命令到服务端
bool result = await tcp.Delete(fileId);
// 返回结果后处理相应的业务
if(result){
// 刷新数据
}
else{
// 提示错误
}
没错,这样子看上去和调用http请求一模一样,是不是逻辑变得简单了?
- 调用示例
画一个时序图吧,我们来看一下调用过程
从上图我们可以看出,和其它网上实例的不同在于,我们自己加了一个task管理模块,我们通过自己对Task进行管理,实现了tcp的异步调用但顺序执行代码。
将以上示例用在实际代码上,效果如下:
- 核心代码
/// <summary>
/// 等待请求
/// </summary>
/// <param name="token">请求的token</param>
/// <param name="timeOut">超时时间</param>
/// <returns></returns>
public async Task<T> Wait(T1 token, TimeSpan timeOut)
{
TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
// 将等待结果的任务加入字典中
TaskDict.Add(token, taskCompletionSource);
try
{
T ret = await taskCompletionSource.Task.WaitAsync(timeOut);
return ret;
}
catch
{
// 如果超时,则移除字典中的任务,并抛出超时异常
if (TaskDict.ContainsKey(token))
{
TaskDict.Remove(token);
}
throw;
}
}
- 结尾
async...await是异步方案的一种,配合TaskCompletionSource可以将分散于2个不同地方的代码合并到一起,对简化代码逻辑来说还是比较靠谱的。
目前这种异步方案已在自己的开源项目(Wireboy.Socket.P2PSocket)中使用了,并且也将此方案适配在了公司项目,主要运用于使用命名管道的进程间通讯。总的来说还是一个比较不错的方案。
- 适用场景
- tcp通讯
- udp通讯
- 命名管道通讯
- UI线程需要大量计算,将计算过程使用线程启动,并通过此方案返回结果。
最新文章
- 织梦cms常用标签
- jquery操作表格 合并单元格
- js 动态添加input代码
- Autofac 依赖注入
- jquery学习笔记----ajax使用
- [POJ1050]To the Max(最大子矩阵,DP)
- 一款jquery编写图文下拉二级导航菜单特效
- Sql Server使用技巧
- JS判断鼠标向上滚动还是向下滚动
- implemented loader.php
- 使用VsCode编写和调试.NET Core项目
- 201521123008《Java程序设计》第10周学习总结
- 利用Java泛型实现简单的泛型方法
- Java基本语法-----java流程控制语句
- 使用 DirectX 创建 3D 图形
- linux下简单的备份的脚本 2 【转】
- matplotlib的下载和安装方法
- 固态盘经常性蓝屏处理方法(WIN7/8)
- C#正则_取出标签内的内容(非贪婪)
- ASP.NET Web Forms 的 DI 應用範例