.Net 异步方法加上“timeout”
在本羊读大学的时候,Thread让本羊云里雾里,代码写的痛不欲生,真的是让本羊脑袋里很多“线”缠绕在一起。
之后,Task让本羊代码写的飞起,甚至有时候根本不需要Task的时候还是要写上,那样显得档次较高:多线程!充分利用CPU!niubility!
再之后,async/await语法糖横空出世,更让本羊欲罢不能!
然而,
好东西吃多了总会腻的——吃货
常在河边走,哪有不湿鞋?——文艺青年
出来混总是要还的——“四道杠”骚年
飙车一时爽,“全家”火葬场——老司机
扯远了,反正大概意思就是,async/await 也会有不爽的时候。
比如:UdpClient.ReceiveAsync()
某领导:只等待5秒,过时不候。这样比较节约性能。
——哎哟,很有道理的样子,那就改改?
于是,本羊很快就找到了一个属性:UdpClient.Client.ReceiveTimeout
UdpClient.Client.ReceiveTimeout=5000;//领导说了只等5秒 <--注释在这里
var r=UdpClient.ReceiveAsync();
……(省略其他代码)
看到没,本羊还很善意的给代码加上了“注释”,方便其他小伙伴理解本羊的优雅的高深的简洁的代码。
然后拿起水杯,小小的抿了一口,伸出右手食指,轻轻的按下“F5”,左手在桌子上很有节奏的敲了5下,哎哟,啥情况?
再敲5下,再敲5下,再敲5下……
好吧,本羊输了。
是时候打开MSDN了,原来,ReceiveTimeout这玩意儿只对同步方法有效,ReceiveAsync根本不管这Y的。
再研究研究?
经过一番刻苦钻研,新的代码来了:
var t=new CancellationTokenSource();//这玩意儿就是用来配合Task,做取消功能的
Task.Delay(5000, t.Token).ContinueWith(task =>
{
if (!task.IsCanceled && task.IsCompleted)//不是被取消而且已经完成
{
client.Close();//释放UdpClient
}
});//咱走着瞧(不会阻塞当前线程),5秒之后再来
try
{
var r=await client.ReceiveAsync();
return r;//返回结果
}
catch
{
throw new TimeoutException("过时不候!");//优雅的抛出错误提示
}
以上代码使用了很长一段时间,直到今天本羊又看到一些关于Task的文章,原来还有更优雅的实现方式!
不多说,上代码:
var t=new CancellationTokenSource();//又是这玩意儿
var r=await Task.WhenAny(client.ReceiveAsync(), Task.Delay(5000, t.Token)) as Task<UdpReceiveResult>;//还是5秒,过时不候
if(r!=null)//如果是Delay先返回,是不能 as Task<UdpReceiveResult>的,r=null。
{
t.Cancel();//取消那个Delay,其实也可以不用处理,反正5秒后那家伙就自己去西天了
return r.Result;
}
else
{
client.Close();//释放UdpClient,不然还是在ReceiveAsync
throw new TimeoutException("过时不候!");
}
再来一个:
var tasks=new Task[]{client.ReceiveAsync()};
var index=awati Task.Run(()=>
{
return Task.WaitAny(tasks, 5000);//返回完成的Task在集合中的序号
});//Wait[xxx]会阻塞线程,所以用一个Run包裹住
if(index==0)
{
return (tasks[0] as Task<UdpReceiveResult>).Result;
}
else
{
client.Close();
throw new TimeoutException("过时不候!");
}
又或者(重磅推荐):
var t = client.ReceiveAsync();
if (await Task.Run(() => { return t.Wait(5000); }))
{
return t.Result;
}
else
{
client.Close();
throw new TimeoutException("过时不候!");
}
CancellationTokenSource、Task.Delay(delay)都用不到了,爽歪歪~~
Wait[xxx]有多个重载,可以设置timeout、CancellationToken,不知道为啥When[xxx]不能设置?
本文到此结束,各位新老司机,点个赞吧!
PS:其实本羊的工作一直是单枪匹马,意思就是公司里只有本羊一个程序猿,所以,某领导是没有的,其他小伙伴也是没有的,一切的一切都是本羊虚构的,包括你们。
.Net 异步方法加上“timeout”的更多相关文章
- Timeout for tests
如果想把timeout太久的测试自动标记为失败,有两种方法: 1.在 @Test里加上 Timeout 参数 定义"timeout=1000“的话,如果超过1000 毫秒,failure会被 ...
- 遇到的问题之“Dubbo 直连 Invoke remote method timeout 问题!”
Dubbo 直连 Invoke remote method timeout 问题! 在测试环境消费者直连服务端进行测试时, 其中一个RPC接口抛出一个错误, 如下: Caused by: com. ...
- 零基础快速入门SpringBoot2.0教程 (三)
一.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...
- 【分布式】Zookeeper会话
一.前言 前面分析了Zookeeper客户端的细节,接着继续学习Zookeeper中的一个非常重要的概念:会话. 二.会话 客户端与服务端之间任何交互操作都与会话息息相关,如临时节点的生命周期.客户端 ...
- 利用 ipset 封禁大量 IP
使用 iptables 封 IP,是一种比较简单的应对网络攻击的方式,也算是比较常见.有时候可能会封禁成千上万个 IP,如果添加成千上万条规则,在一台注重性能的服务器或者本身性能就很差的设备上,这就是 ...
- Java多线程开发技巧
很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...
- 小白日记7:kali渗透测试之主动信息收集-发现(一)--二层发现:arping/shell脚本,Netdiscover,scapy
主动信息收集 被动信息收集可能不准确,可以用主动信息收集验证 特点:直接与目标系统交互通信,无法避免留下访问痕迹 解决方法:1.使用受控的第三方电脑进行探测,使用代理 (做好被封杀的准备) 2 ...
- 小白日记8:kali渗透测试之主动信息收集(二)三层发现:ping、traceroute、scapy、nmap、fping、Hping
三层发现 三层协议有:IP以及ICMP协议(internet管理协议).icmp的作用是用来实现intenet管理的,进行路径的发现,网路通信情况,或者目标主机的状态:在三层发现中主要使用icmp协议 ...
- urllib2.urlopen超时问题
urllib2.urlopen超时问题 没有设置timeout参数,结果在网络环境不好的情况下,时常出现read()方法没有任何反应的问题,程序卡死在read()方法里,搞了大半天,才找到问题,给ur ...
随机推荐
- Flex各类型坐标转换(全局、本地、内容坐标间转换)
Flex包含3种坐标:全局坐标.本地坐标.内容坐标 全局坐标:stage级别,坐标原点为舞台的左上角,如MouseEvent的stageX.stageY坐标. 本地坐标:组件级别的坐标系,相对坐标,坐 ...
- 十五天精通WCF——第十三天 用WCF来玩Rest
在我们玩wcf的时候,都会潜意识的觉得wcf就是通过soap协议交换消息的,并且可以在basic,tcp,msmq等等绑定中任意切换, 牛逼的一塌糊涂,但是呢,如果说哪一天wcf不再使用soap协议, ...
- (企业面试部分)超详细思路讲解SQL语句的查询实现,及数据的创建。
企业面试部分详细的SQL问题,思路讲解 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CREATE TABLE student( sno ) ...
- python极客学院爬虫V1
定向爬取极客学院视频,原本只有年费VIP只能下载,经过分析,只要找个免费体验VIP即可爬取所有视频 涉及的基本技术:python xpath 正则 com+ 通过python调用迅雷从组件,实现自动创 ...
- PHP生成器Generators
下文的第一个逐行读取文件例子用三种方式实现;普通方法,迭代器和生成器,比较了他们的优缺点,很好,可以引用到自己的代码中 ,支持的php版本(PHP 5 >= 5.5.0) 后面的yield讲解, ...
- PlaceHolder的两种实现方式
placeholder属性是HTML5 中为input添加的.在input上提供一个占位符,文字形式展示输入字段预期值的提示信息(hint),该字段会在输入为空时显示. 如 <input typ ...
- python抓取网页中图片并保存到本地
#-*-coding:utf-8-*- import os import uuid import urllib2 import cookielib '''获取文件后缀名''' def get_file ...
- 利用网络流传的WebShell默认密码库寻找WebShell
声明:本文提到的技术,仅可用作网络安全加固等合法正当目的.本文作者无法鉴别判断读者阅读本文的真实目的,敬请读者在本国法律所允许范围内阅读本文,读者一旦因非法使用本文提到技术而违反国家相关的法律法规,所 ...
- Linux下ejabberd开机自启(CentOS)
废话少说,Linux下开机自启动Ejabberd步骤如下: 1.从ejabberd安装目录的bin目录拷贝ejabberd.init到/etc/init.d/ejabberd下 [root@imser ...
- NOIP2010提高组乌龟棋 -SilverN
题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...