async...await在tcp通讯中的正确用法
- 引言
编程能力在不断的总结中进步以及成长,最近的半年里,对之前的开源项目代码进行回归,在重构的过程中进行了很多思考,很多次都想放弃重构,毕竟一个已经在使用的项目,重构基础代码就相当于重新开发了,不过最终还是下定了决心,毕竟重构就是一个成长过程,要想进步,就要不断的发现原有代码的不足,使用新的思维去优化原来的东西,在重构的过程中,针对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线程需要大量计算,将计算过程使用线程启动,并通过此方案返回结果。
async...await在tcp通讯中的正确用法的更多相关文章
- 使用netty实现的tcp通讯中如何实现同步返回
在netty实现的tcp通讯中,一切都是异步操作,这提高了系统性能,但是,有时候client需要同步等待消息返回,如何实现呢?笔者已经实现,在此总结下重点要素 实现要点: 1.消息结构设计 消息头中需 ...
- tcp通讯中socket套接字accept和listen的关系
今天看到一个文章,客户端的connect在服务端调用accept之前,突然想到这可以建立正常的连接么?以前从没细细的思考过listen accept connect之前的关系,带着疑问学习了一下,记录 ...
- Guava的RateLimiter在单机限流中的正确用法
错误使用 在实现限流时,网上的各种文章基本都会提到Guava的RateLimiter,用于实现单机的限流,并给出类似的代码: public void method() { RateLimiter ra ...
- 实际案例:在现有代码中通过async/await实现并行
一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色30秒”问题的过程中,切身体会到了异步的巨大作用 ...
- 在Silverlight中使用async/await
现在 async/await 大行其道,确实,有了 async/await ,异步编程真是简单多了,个人觉得 async/await 的出现,给开发者还来的方便,绝不亚于当年 linq 的出现. 但要 ...
- 在现有代码中通过async/await实现并行
在现有代码中通过async/await实现并行 一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色 ...
- Javascript中的async await
async / await是Javascript是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案.目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度 ...
- 理解C#中的 async await
前言 一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解.(PS:文中涉及到了大量反编译源码,需要静下心来细细品味) 从简单开始 为了更容易理解 ...
- .Net Core中无处不在的Async/Await是如何提升性能的?
一.简介 Async/Await在.Net Core中真的是无处不在,到处都是异步操作,那为什么要用?有什么作用?别人说能提升性能?网上一堆文章看的绕晕了也没说清楚, 所以这里从理论,实践,原理一个个 ...
随机推荐
- ATM+购物车项目流程
目录 需求分析 架构设计 功能实现 搭建文件目录 conf配置文件夹 lib公共功能文件夹 db数据文件夹 interface业务逻辑层文件夹 core表现层文件夹 测试 最外层功能(src.py) ...
- 【Java面试】请说一下Mysql索引的优点和缺点?
今天分享的这道面试题,让一个工作4年的小伙子去大众点评拿了60W年薪. 这道面试题是: "请你说一下Mysql索引的优点和缺点" 关于这道题,看看普通人和高手的回答 普通人: 嗯. ...
- ACM-01背包问题-Python
日后完善 二维数组实现 if __name__ == '__main__': # 背包空间 space = 10 # 默认第一个元素为 0, 仅仅是为了方便理解 weights = [0, 2, 2, ...
- WPF第三方控件,只能输入数字型数据
话不多说,根据最近项目需求,为了减少输入验证等相关代码量,需要此控件 先上效果图 默认样式是这样,自己可以根据需求修改外形,但我更喜欢它自带的简洁版 有人可能会问怎么实现的呢?其实很简单,我们设置它的 ...
- Jenkins + maven + svn 自动部署项目
1.安装Jenkins sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins. ...
- CPI教程-异步接口创建及使用
CPI教程-异步接口创建及使用 create by yi 转载请注明出处 先简单介绍一下同步接口和异步接口 什么是同步接口 同步接口的意思就是发送方发送Message后,接口方处理完成后会立刻返回执行 ...
- Halcon 模板匹配实战代码(一)
模板图片:目标是获取图像左上角位置的数字 直接想法,直接用一个框将数字框出来,然后对图片进行模板匹配(不可行,因为图像中的数字不是固定的) 所以需要选择图像中的固定不变的区域来作为模板,然后根据模板区 ...
- Intel的CPU系列说明
至强可扩展系列是英特尔推出的新一代至强处理器系列,如今距离该系列推出几乎过去一年了.新的CPU并没有延续E系列的命名,英特尔将至强可扩展系列以金属命名,将该系列分为"铂金Platinum&q ...
- Python中print()函数的用法详情
描述 print() 方法用于打印输出,最python中常见的一个函数. 在交互环境中输入help(print)指令,可以显示print()函数的使用方法. >>> help(pri ...
- 基于单层决策树的AdaBoost算法原理+python实现
这里整理一下实验课实现的基于单层决策树的弱分类器的AdaBoost算法. 由于是初学,实验课在找资料的时候看到别人的代码中有太多英文的缩写,不容易看懂,而且还要同时看代码实现的细节.算法的原理什么的, ...