基于任务的异步编程(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 ...
随机推荐
- 关于Java中Collections.sort和Arrays.sort的稳定性问题
一 问题的提出 关于Java中Collections.sort和Arrays.sort的使用,需要注意的是,在本文中,比较的只有Collections.sort(List<T> ele ...
- golang 实现求两向量夹角
type Vector3 struct { X float64 `json:"x"` Y float64 `json:"y"` Z float64 `json: ...
- python-实现输出乘法口诀表
list1 = [1,2,3,4,5,6,7,8,9] 2 def number(num): 3 for i in list1[:num]: 4 result = 1 * i 5 print(&quo ...
- 白话解读 WebRTC 音频 NetEQ 及优化实践
NetEQ 是 WebRTC 音视频核心技术之一,对于提高 VoIP 质量有明显的效果,本文将从更为宏观的视角,用通俗白话介绍 WebRTC 中音频 NetEQ 的相关概念背景和框架原理,以及相关的优 ...
- Linux wget 使用笔记
wget 是 Linux 上最常用的文件下载工具,简单实用.记录一下一些常用的操作备查. 最常用最简单的操作就是直接使用一个 URL 下载 下载互联网上指定的文件 wget https://gemme ...
- java例题_12 奖金问题(暴力破解)
1 /*12 [程序 12 计算奖金] 2 题目:企业发放的奖金根据利润提成. 3 利润I低于或等于 10 万元时,奖金可提 10%: 4 利润高于 10 万元,低于 20 万元时,低于 10 万元的 ...
- [Fundamental of Power Electronics]-PART I-4.开关实现-4.3 开关损耗/4.4 小结
4.3 开关损耗/4.4 小结 使用半导体器件实现开关后,我们现在可以讨论变换器中损耗和低效的另一个主要来源:开关损耗.如前所述,半导体器件的导通和关断转换需要几十纳秒到几微秒的时间.在这些开关转换期 ...
- Sql Server Report Service访问服务页面503解决方法
这个问题可能性比较多,也有多个方案去解决,可以从如下方法里逐个测试 1.打最新的数据库补丁. 2.删除报表服务配置的密钥,重启报表服务. 3.修改报表服务器配置的用户账户为域管理员 4.找到报表服务器 ...
- 北航OO第四单元作业总结(4.1~4.3)及课程总结
前言 在学习过JML规格描述语言之后,本单元进行了UML(Unified Modeling Language)的学习.和JML单纯用语言描述的形式不同,UML通过可视化的图形形式,对一系列有关类的元素 ...
- ubuntu apt出错
whitedream@ubuntu:~$ sudo apt-get update Reading package lists... Done E: Could not get lock /var/li ...