2.1 暂停一段时间

问题
需要让程序(以异步方式)等待一段时间。这在进行单元测试或者实现重试延迟时非常
有用。本解决方案也能用于实现简单的超时。

解决方案
Task 类有一个返回Task 对象的静态函数Delay,这个Task 对象会在指定的时间后完成。

Delay方法的重载:

public static Task Delay(TimeSpan delay);
public static Task Delay(TimeSpan delay, CancellationToken cancellationToken);
public static Task Delay(int millisecondsDelay);
public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken);

书中给出三个例子。
一个是单元测试中,定义一个异步完成的任务,以完成“异步成功”测试。

static async Task<T> DelayResult<T>(T result, TimeSpan delay)
{
    await Task.Delay(delay);
    return result;
}

一个是指数退避的简单实现

指数退避是一种重试策略,重试的延迟时间会逐次增加。在访问 Web 服务时,最好的方式就是采用指数退避,它可以防止服务器被太多的重试阻塞。

书中提到实际产品开发中,应对指数退避重试机制有更周密的解决方案。书中推荐了微软企业库中的瞬间错误处理模块(Transient Error Handling Block),在微软Docs中找到了相关文章。
暂时性故障处理 (构建使用 Azure 的真实世界云应用程序):
https://docs.microsoft.com/zh-cn/aspnet/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/transient-fault-handling

 static async Task<string> DownloadStringWithRetries(string uri)
        {
            using (var client = new HttpClient())
            {
                // 第 1 次重试前等 1 秒,第 2 次等 2 秒,第 3 次等 4 秒。
                var nextDelay = TimeSpan.FromSeconds(1);
                for (var i = 0; i != 3; ++i)
                {
                    try
                    {
                        return await client.GetStringAsync(uri);
                    }
                    catch
                    {
                    }
                    await Task.Delay(nextDelay);
                    nextDelay = nextDelay + nextDelay;
                }
                // 最后重试一次,以便让调用者知道出错信息。
                return await client.GetStringAsync(uri);
            }
        }

上述代码实现的是对异步get请求进行多次重试。

最后一个例子,是实现了一个简单的超时功能,当get请求在3秒内没有响应,返回null。

        static async Task<string> DownloadStringWithTimeout(string uri)
        {
            using (var client = new HttpClient())
            {
                var downloadTask = client.GetStringAsync(uri);
                var timeoutTask = Task.Delay(3000);
                var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
                if (completedTask == timeoutTask)
                    return null;
                return await downloadTask;
            }
        }

该代码的实现主要是借助于Task.WhenAny方法。
Task.WhenAny的返回值是提供的多个任务中已完成的任务。
如果已完成的任务completedTasktimeoutTask相等,证明最先完成的任务是等待三秒之后完成的任务timeoutTask,也就是说downloadTask没有在三秒内完成。

原文地址:https://www.cnblogs.com/zachchen/p/10950711.html

时间: 2024-08-30 14:47:44

2.1 暂停一段时间的相关文章

ubuntu16.04 无法wifi链接一段时间掉线且无法再连接

ubuntu16.04 无法wifi链接一段时间掉线且无法再连接,从网上搜索的确认这个一个bug. 解决方法: 1.Get details of your PCI wireless card by running sudo lshw -class network 显示信息如下: *-network description: Wireless interface product: RTL8723BE PCIe Wireless Network Adapter vendor: Realtek Sem

为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

在做更新,在测试异常的时候,在下载过程中,发现如果直接系统禁用了网络,会报错误,可以捕获.但是如果是第三方软件限制程序联网,问题来了. 程序会一直在那里等待,没有异常,也不发送QNetworkAccessManager::finsh和QNetworkReply::error和QNetworkReply::finsh信号. 所以动念头为下载加个超时,但是QNetworkAccessManager,QNetworkReply和QNetworkRequest都没有相关的设置函数.其实仔细想一下,也没有

快到这段时间的终点了。。。

总结一下自己最近的问题. (1)生活 比较懒散,学习了一段时间前端以后,渐渐忘记了实际上是一个写C++的.应该有时间的时候,写点C++的代码,试着解决一些复杂一点算法, 应该向——向总学习,最近一个月搞定了2个机器学习的算法,额,惭愧,应该花点时间撸一撸算法的.最近还是过的太懒散了. (2)学习的惯性应该保持,时刻保持一颗学习的心,这个行业大部分都是平庸的人.只有极少数才是行业领袖,业界精英.所以,能坚持到最后的,都有机会 成为行业精英,所以,最好比的是时间,因为除了极少数的天才,大部分都是靠时

网站部署中遇到的问题-过一段时间后连不上服务器

问题描述: 这个情况我只针对局域网说明,我在一个局域网内用电脑A作为服务器,并部署站点site1.在这个局域网内的电脑可以正常访问site1. 可是过一段时间后无法访问site1,重新登录A后,又恢复了对site1的访问. 原因: 设置了电脑的睡眠时间. 解决方法: 将电脑A的的睡眠时间设置为"从不".设置步骤:控制面板—>电源—>更改睡眠时间.

java linux ImageIO 验证码在一段时间以后出不来 问题总结

最近在测试上布署的项目经常性的出现验证码过了一段时间以后出不来的情况,耐心找了一下,最后在上级的指导下发现了报错,其实说真的,我自己也找到了这个报错,只是没有当一回事.因为这个验证码的东西不是我写的,我也不知道这个报错是不是和它有关系. 错误如下: 2014-05-21 10:46:17,826 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Could not complete request org.springfram

前一段时间的混乱岁月总结和下一阶段展望

前段时间虽然断断续续地在学,但是状态极其不佳,下面分析原因: 1.晚上玩手机:下午学了一些东西->感觉很充实->晚上想玩->决定带手机回寝室,认为自己只需要玩一会就可以睡觉->晚上玩得昏天黑地->白天死睡,睡了一个上午->后悔,自责->下午开始学习,没精神,想睡觉->下午学了一些东西->进入循环 2.学习,放松,生活三者之间的关系:这其中:学习和生活都应该得到重视,特别是生活:不要忽视他,应该把它放到与学习平等的地位,好的愉快地生活习惯会反哺学习,好的

搞了一段时间iOS开发的感受

接触iOS有了一小段的时间了,属于半路出家,之前只是对C和数据结构有一些了解并不深入,Objective-C算是第一门较为深入的了解吧,知道自己在各个方面都差的很远,需要学习的东西很多很多. 第一个阶段就是基础的学习,熟悉UIFoundation和UIKit的基础框架,能自己写些简单的app,花了几个月的时间.掌握了这部分的基础知识后,开始在公司做项目,开始看写app发现自己好多实现都无从下手,当然还有很多看不到的地方,于是就开始看一些code4app和github上的代码,先看example,

关于ScheduledExecutorService执行一段时间之后就不执行的问题

问题背景 最近写了个程序,程序中使用到了ScheduledExecutorService的scheduleAtFixedRate方法,用于定时执行任务,但是发现程序运行一段时间之后定时任务不执行了,查看日志和perfcounter都没有看到任何异常,比较郁闷.最后看了一下JDK的源码,在源码的Java doc中的发现了如下一句话: If any execution of the task encounters an exception, subsequent executions are sup

Linux解决:svn: Can&#39;t connect to host &#39;*.*.*.*&#39;: 由于连接方在一段时间后没有正确答复或连接

svn服务启动了,在服务器上可以使用命令把文件检出,但是其他电脑上就无法检出,一直提示: "svn: Can't connect to host '*.*.*.*': 由于连接方在一段时间后没有正确答复或连接" 在网上找了半天说什么没有启动服务什么的,废话,没起服务玩蛋呀. 我通过检查防火墙看到3690端口根本没有对外开放,通过修改配置文件,解决问题: 修改如下: [[email protected] home]# more /etc/sysconfig/iptables # Fire