问题:

需要让程序(以异步方式)等待一段时间。

解决方案:Task类的静态函数Delay,返回Task对象

在github开源项目dotnet/coreclr,找到Task.cs有关Delay方法的源码

github地址:

https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs

        /// <summary>
/// Creates a Task that will complete after a time delay.
/// </summary>
/// <param name="millisecondsDelay">The number of milliseconds to wait before completing the returned Task</param>
/// <returns>A Task that represents the time delay</returns>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// The <paramref name="millisecondsDelay"/> is less than -1.
/// </exception>
/// <remarks>
/// After the specified time delay, the Task is completed in RanToCompletion state.
/// </remarks>
public static Task Delay(int millisecondsDelay)
{
return Delay(millisecondsDelay, default);
}

Delay方法会创建一个延迟millisecondsDelay 毫秒后完成的任务。

millisecondsDelay 为 在完成返回的任务前要等待的毫秒数,如果值为-1,将无限期等待。

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的返回值是提供的多个任务中已完成的任务。

如果已完成的任务completedTask和timeoutTask相等,证明最先完成的任务是等待三秒之后完成的任务timeoutTask,也就是说downloadTask 没有在三秒内完成。

《C#并发编程经典实例》学习笔记—2.1 暂停一段时间的更多相关文章

  1. 《C#并发编程经典实例》笔记

    1.前言 2.开宗明义 3.开发原则和要点 (1)并发编程概述 (2)异步编程基础 (3)并行开发的基础 (4)测试技巧 (5)集合 (6)函数式OOP (7)同步 1.前言 最近趁着项目的一段平稳期 ...

  2. 《C#并发编程经典实例》学习笔记—2.7 避免上下文延续

    避免上下文延续 在默认情况下,一个 async 方法在被 await 调用后恢复运行时,会在原来的上下文中运行. 为了避免在上下文中恢复运行,可让 await 调用 ConfigureAwait 方法 ...

  3. 《C#并发编程经典实例》学习笔记—3.1 数据的并行处理

    问题 有一批数据,需要对每个元素进行相同的操作.该操作是计算密集型的,需要耗费一定的时间. 解决方案 常见的操作可以粗略分为 计算密集型操作 和 IO密集型操作.计算密集型操作主要是依赖于CPU计算, ...

  4. 《C#并发编程经典实例》学习笔记—2.3 报告任务

    问题 异步操作时,需要展示该操作的进度 解决方案 IProgress<T> Interface和Progress<T> Class 插一段话:读<C#并发编程经典实例&g ...

  5. 《C# 并发编程 · 经典实例》读书笔记

    前言 最近在看<C# 并发编程 · 经典实例>这本书,这不是一本理论书,反而这是一本主要讲述怎么样更好的使用好目前 C#.NET 为我们提供的这些 API 的一本书,书中绝大部分是一些实例 ...

  6. [书籍]用UWP复习《C#并发编程经典实例》

    1. 简介 C#并发编程经典实例 是一本关于使用C#进行并发编程的入门参考书,使用"问题-解决方案-讨论"的模式讲解了以下这些概念: 面向异步编程的async和await 使用TP ...

  7. 《C#并发编程经典实例》学习笔记-关于并发编程的几个误解

    误解一:并发就是多线程 实际上多线程只是并发编程的一种形式,在C#中还有很多更实用.更方便的并发编程技术,包括异步编程.并行编程.TPL 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并 ...

  8. 《C#并发编程经典实例》学习笔记-第一章并发编程概述

    并发编程的术语 并发 同时做多件事情 多线程 并发的一种形式,它采用多个线程来执行程序. 多线程是并发的一种形式,但不是唯一的形式. 并行处理 把正在执行的大量的任务分割成小块,分配给多个同时运行的线 ...

  9. 并发编程概述--C#并发编程经典实例

    优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版.NET 中的程序库和语 ...

随机推荐

  1. windows下qt的.exe的dll文件怎么配齐

    用qt自带的windeploy工具即可 win键打开开始菜单 找到qt目录下的qt for desktop(mingw)并打开 qtcreater或者vs打开要部署的项目,构建成release模式,运 ...

  2. idea 新建项目上传至git(coding)

    一.新建项目 1.改为git版本 2.出现如下框 选择Git 3.新建一个.gitignore file (Git) 4.勾掉一些不需要的 5.出现如下框 5.1.如果不知道.gitignore fi ...

  3. win10 win7 环境下 oracle 11g和Plsql的安装、卸载遇到的问题。

    * win7一体机在安装好oracle和PlSQL后,无法连接到orcl数据库,同时也忘记了sys设置的密码.(在这里应注意在安装过程中,应选择统一口令,这里我均设置成了orcl,同时也应该注意在最后 ...

  4. repo 用法

    repo的用法(zz) 注:repo只是google用Python脚本写的调用git的一个脚本,主要是用来下载.管理Android项目的软件仓库.(也就是说,他是用来管理给git管理的一个个仓库的) ...

  5. 虚拟机Linux不能上网简单有效的解决办法

    对于刚开始接触Linux系统的用户来说,先使用虚拟机Linux学习是不错的选择.但是在用虚拟机上网的时候,总是出现这样那样的错误,到底该怎么办呢?本文笔者和大家分享一下虚拟机Linux不能上网的简单有 ...

  6. Python OR & AND

    These are the Boolean operations, ordered by ascending priority: Operation Result Notes x or y if x ...

  7. mybatis 中的缓冲

    package com.oaec.mybatis.test; import com.oaec.mybatis.dao.StudentDao;import com.oaec.mybatis.entity ...

  8. JavaScript之DOM创建节点

    上几篇文章中我们罗列了一些获取HTML页面DOM对象的方法,当我们获取到了这些对象之后,下一步将对这些对象进行更改,在适当的时候进行对象各属性的修改就形成了我们平时看到的动态效果.具体js中可以修改D ...

  9. 电商门户网站商品品类多级联动SpringBoot+Thymeleaf实现

    在淘宝.京东等电商网站,其门户网站都有一个商品品类的多级联动,鼠标移动,就显示,因为前端不是我做的,所以不说明前端实现,只介绍后端实现. 搭建部署SpringBoot环境 配置文件配置: 开启了对Th ...

  10. Python并发目录

    Python并发目录 Python-socket网络编程 Python网络编程-IO阻塞与非阻塞及多路复用 Python进程-理论 Python进程-实现 Python进程间通信 Python进程池 ...