在本羊读大学的时候,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”的更多相关文章

  1. Timeout for tests

    如果想把timeout太久的测试自动标记为失败,有两种方法: 1.在 @Test里加上 Timeout 参数 定义"timeout=1000“的话,如果超过1000 毫秒,failure会被 ...

  2. 遇到的问题之“Dubbo 直连 Invoke remote method timeout 问题!”

    Dubbo 直连 Invoke remote method timeout 问题!   在测试环境消费者直连服务端进行测试时, 其中一个RPC接口抛出一个错误, 如下: Caused by: com. ...

  3. 零基础快速入门SpringBoot2.0教程 (三)

    一.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...

  4. 【分布式】Zookeeper会话

    一.前言 前面分析了Zookeeper客户端的细节,接着继续学习Zookeeper中的一个非常重要的概念:会话. 二.会话 客户端与服务端之间任何交互操作都与会话息息相关,如临时节点的生命周期.客户端 ...

  5. 利用 ipset 封禁大量 IP

    使用 iptables 封 IP,是一种比较简单的应对网络攻击的方式,也算是比较常见.有时候可能会封禁成千上万个 IP,如果添加成千上万条规则,在一台注重性能的服务器或者本身性能就很差的设备上,这就是 ...

  6. Java多线程开发技巧

    很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...

  7. 小白日记7:kali渗透测试之主动信息收集-发现(一)--二层发现:arping/shell脚本,Netdiscover,scapy

    主动信息收集 被动信息收集可能不准确,可以用主动信息收集验证   特点:直接与目标系统交互通信,无法避免留下访问痕迹 解决方法:1.使用受控的第三方电脑进行探测,使用代理 (做好被封杀的准备)   2 ...

  8. 小白日记8:kali渗透测试之主动信息收集(二)三层发现:ping、traceroute、scapy、nmap、fping、Hping

    三层发现 三层协议有:IP以及ICMP协议(internet管理协议).icmp的作用是用来实现intenet管理的,进行路径的发现,网路通信情况,或者目标主机的状态:在三层发现中主要使用icmp协议 ...

  9. urllib2.urlopen超时问题

    urllib2.urlopen超时问题 没有设置timeout参数,结果在网络环境不好的情况下,时常出现read()方法没有任何反应的问题,程序卡死在read()方法里,搞了大半天,才找到问题,给ur ...

随机推荐

  1. jquery最常用的几个方法。

    jquery使用手册:http://www.eduyo.com/doc/jquery/cheatsheet.html addClass 样式: <style> .textRed { col ...

  2. 烂泥:高负载均衡学习haproxy之关键词介绍

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 上一篇文章我们简单讲解了有关haproxy的安装与搭建,在这篇文章我们把haproxy配置文件中使用到的关键词一一介绍下. 关注我微信ilann ...

  3. Xcode同时兼容Xcode7和Xcode8,两个版本并存,也适用于先升8再安装7

    先吐槽一下之前看到的一个教程,如下: 先在应用程序内,拷贝一份之前的xcode,然后再安装新版本,发现这种安装完成就是在之前上面迭代了  有木有?等于没任何作用 我这边就是不小心先升级了8,然后再安装 ...

  4. date

    更改时区 用系统备好的时区文件覆盖掉当前的配置文件,/etc/里装的是当前系统的配置文件 $sudo cp /usr/share/zoneinfo/Asia/Chongqing /etc/localt ...

  5. x01.os.9: 进程切换

    进入内核后,当然不能无所事事.先创建三个进程,分别打印 A,B,C.虽然只是简单的打印,但却是一切扩展的基础,不可等闲视之. 进程切换,涉及一系列的寄存器需要保护,于是,就有了 ProcessStac ...

  6. 双核CPU,跑程序会报rcu_sched_state detected stalls on CPUs/tasks 错误

    有一份SDK,之前跑在PPC405EX上没问题。最近换平台,CPU使用了PowerPC的P1020,双核。linux版本也升级到了3.0.48版本。升级之后出现了一个问题:SDK里面的程序跑一段时间之 ...

  7. exe文件无法打开

    1.现象 在一个XP 64位机子上从IE下载一个exe文件后,双击竟然无任何反应,以为文件有问题,但多次尝试后仍是如此,但打开cmd通过命令行启动是正常,双击该机子上其他exe文件也都能启动,但从IE ...

  8. MMORPG大型游戏设计与开发(客户端架构 part12 of vegine)

    在游戏中的交互过程中输入是一个必不可少的过程,比如登陆的时候需要用户输入用户名与密码,就算是单机游戏很多时候也要求用户输入一个用户名作为存档的依据.网络游戏中没有了输入,只用鼠标来交互是不切实际的,因 ...

  9. MMORPG大型游戏设计与开发(客户端架构 part2 of vegine)

    一个好的接口是尽可能让更多实用的方法进行整理封装,要记住的是不常用的方法和类最好不好封装到接口中,因为那样会造成本身的困惑.基础模块中并没有太多封装,甚至连一个类的封装也没有,而是一些很常用的工具方法 ...

  10. java 24 - 10 GUI 之 四则预算的数据校验

    我想要在校验的过程中,如果输入到操作数中的不是数字,则弹出提醒框: 类 JOptionPane  有助于方便地弹出要求用户提供值或向其发出通知的标准对话框 方法名 描述 showConfirmDial ...