基于任务的异步编程(Task,async,await)
这节讲一下比较高级的异步编程用法Task,以及两个异步关键字async和await。
Task是在C#5.0推出的语法,它是基于任务的异步编程语法,是对Thread的升级,也提供了很多API,先看一下Task怎么使用:
System.Threading.Tasks.Task.Run(() =>
{
Console.WriteLine("异步");
});
System.Threading.Tasks.Task aTask=new System.Threading.Tasks.Task(() =>
{
Console.WriteLine("异步");
});
aTask.Start();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
Console.WriteLine("异步");
});
Task.Run()可以直接异步运行一个方法,或者使用实例化Task传入委托的方式,通过start()进行启动,再或者使用Task.Factory.StartNew()直接启动。
async,await
为了进一步介绍Task,需要先介绍两个异步有关的关键字async,await
async用在方法的声明,await用于代码语句中。被async标记的方法,称作异步方法。但是,并非整个方法都是异步执行,代码中以await开头标记的代码,才是要真正异步执行的具体内容。这个关键字一般是配合Task来使用的,Task有泛型的形式,标识异步的返回值类型,通过Result()方法获取返回值。这段说明很难理解,下面看代码演示:
static void Main(string[] args)
{
Console.WriteLine("新建一个异步任务");
Task<int> task = new Program().GetValue();
Console.WriteLine("正在计算结果....");
Console.WriteLine($"运行结果为:{task.Result}");
Console.WriteLine("任务完成....");
}
public async Task<int> GetValue()
{
Console.WriteLine("即将开始进行计算...3");
Console.WriteLine("即将开始进行计算...2");
Console.WriteLine("即将开始进行计算...1");
int a= await System.Threading.Tasks.Task.Run(() =>
{
int i = 0;
for (; i < 10; i++)
{
Console.WriteLine(i);
}
return i;
});
Console.WriteLine("结果计算完成....");
return a;
}
运行结果为:

从运行结果可以看出,程序运行到15行await处后,下一步就跳出了这个方法,回到第6行执行,这也是await的一个特性,异步执行,将主线程执行权交回,也就是说,从15行到25行是在后台线程中执行的,之前的执行都是同步的,之后的执行也是同步的,而且,主线程的脚步没有停下,直到遇到task.Result,Result里边存放着异步方法运行的返回值,运行到这,如果异步没有完成,就会阻塞当前线程,直到异步返回结果。
另外说一点,之前在讲自定义中间件的时候,涉及到过这两个关键词,现在明白了这个用法,可以回去再看一下,应该会对中间件的访问流程有一个更清晰的理解。
ContinueWith
ContinueWith设置Task在执行完原有任务后,再继续执行此方法设置的方法,下面看代码:
task.ContinueWith((task) =>
{
Console.WriteLine("---------------"+a.Result);
});
这是其中的一个重载,接受一个Action<Task<T>>类型的委托,此处乍一看可能会不解,其实就是把当前执行任务的Task对象传进来了。这样的用法有什么好处呢,运行完了以后,可以直接取Task任务的返回值,不用阻塞线程,当然这是在返回值不是急需的情况下。
CancellationTokenSource
CancellationTokenSource类用于终止一个任务,请先看一下代码:
static void Main(string[] args)
{
CancellationTokenSource cancellationToken=new CancellationTokenSource();
Task<int> task= new Program().GetValue(cancellationToken);
cancellationToken.Cancel();
Console.WriteLine("正在计算结果....");
Console.WriteLine($"运行结果为:{task.Result}");
Thread.Sleep(1000);
Console.WriteLine("任务完成....");
}
public Task<int> GetValue(CancellationTokenSource cancellationToken)
{
Task<int> a = System.Threading.Tasks.Task.Run(() =>
{
int i = 0;
for (; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
return i;
},cancellationToken.Token);
Console.WriteLine("结果计算完成....");
return a;
}
创建一个CancellationTokenSource对象,在Run任务的时候传入一个Token,就能调用Cancel()方法就能终止这个任务,运行结果为:
可以看到报错了,这很正常,因为任务停止了,显然Result是没有值的
最后注意一点,异步不是多线程,可以说异步是基于多线程,但是它们不是等于的关系。
这是我的公众号二维码,获取最新文章,请关注此号

基于任务的异步编程(Task,async,await)的更多相关文章
- C# 异步编程(async&await)
同步:同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去 异步:异步是指进程不需要一直等下去,而是继续执行下面的操作 ...
- 异步编程(async&await)
前言 本来这篇文章上个月就该发布了,但是因为忙 QuarkDoc 一直没有时间整理,所以耽搁到今天,现在回归正轨. C# 5.0 虽然只引入了2个新关键词:async和await.然而它大大简化了异步 ...
- 学习迭代器实现C#异步编程——仿async/await(一)
.NET 4.5的async/await真是个神奇的东西,巧妙异常以致我不禁对其实现充满好奇,但一直难以窥探其门径.不意间读了此篇强文<Asynchronous Programming in C ...
- python3.6以上 asyncio模块的异步编程模型 async await语法
这是python3.6以上版本的用法,本例是python3.7.2编写使用asyncio模块的异步编程模型,生产这消费者,异步生产,用sleep来代替IO等待使用async和await语法来进行描述a ...
- c# 异步编程demo (async await)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- ASP.NET 异步编程之Async await
本文重点介绍的是.NET Framework4.5 推出的异步编程方案 async await 请先看个5分钟的微软演示的视频:视频地址: https://channel9.msdn.com/Blo ...
- .Net 4.5 异步编程初试(async和await)
.Net 4.5 异步编程初试(async和await) 前言 最近自己在研究Asp.Net Web API.在看到通过客户端来调用Web API的时候,看到了其中的异步编程,由于自己之前没有接触过, ...
- 异步编程(Async和Await)的使用
.net4.5新特性之异步编程(Async和Await)的使用 一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个“主题”.即:C#1.0托管代码→C#2. ...
- 基于任务的异步编程模式,Task-based Asynchronous Pattern
术语: APM 异步编程模型,Asynchronous Programming Model,其中异步操作由一对 Begin/End 方法(如 FileStream.BeginRea ...
随机推荐
- c++ 反汇编 if
1.debug if: 10: if (argc == 0) 0010711E 83 7D 08 00 cmp dword ptr [argc],0 00107122 75 11 jne If+35h ...
- 从本质彻底精通Git——4个模型1个周期1个史观1个工作流
一.什么是Git? Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是Linus Torvalds为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软 ...
- HTML(二):HTML常用标签(上)
标签语义 学习标签是有技巧的,重点是记住每个标签的语义.简单理解就是指标签的含义,即这个标签是用来干嘛的. 根据标签的语义,在合适的地方给一个最为合理的标签,可以让页面结构更清晰. 标题标签<h ...
- centos 7升级gcc到10.2.0
安装gcc 由于 Linux 操作系统的自由.开源,在其基础上衍生出了很多不同的 Linux 操作系统,如 CentOS.Ubuntu.Debian 等.这些 Linux 发行版中,大多数都默认装有 ...
- Dynamics CRM证书更换
Dynamics CRM产品一般有两种认证方式.第一种是基于声明的内部访问也就是无证书单纯用账号密码验证.第二种就是联合身份认证,需要安装网站证书. 对于联合身份认证的情况因为需要安装证书,而且证书是 ...
- Dynamics CRM安装教程九(续):自建证书的CRM项目客户端设置CRM访问
配置完IFD之后就可以为客户端电脑配置访问CRM了首先到CA证书服务器中把证书下载下来,打开CA服务器的浏览器,输入地址http://stg-ad/certsrv/ 其中stg-ad是机器名之后点击下 ...
- 《构建之法》& CI/CD调研
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 2021年软工-个人阅读作业2 我在这个课程的目标是 提升软件开发能力与团队意识 这个作业在哪个具体方面帮助 ...
- 采用QT技术,开发OFD电子文档阅读器
前言 ofd作为板式文档规范,相当于国产化的pdf.由于pdf标准制定的较早,相关生态也比较完备,市面上的pdf阅读器种类繁多.国内ofd阅读器寥寥无几,作者此前采用wpf开发了一款阅读器,但该阅读器 ...
- Spring Boot 整合Junit和redis
14. Spring Boot整合-Junit 目标:在Spring Boot项目中使用Junit进行单元测试UserService的方法 分析: 添加启动器依赖spring-boot-starter ...
- Tensorflow Serving 参数
Flags: --port=8500 int32 Port to listen on for gRPC API --grpc_socket_path="" string If no ...