C#线程学习笔记八:async & await入门一
一、涉及内容
async & await是C# 5.0引入的,控制台输出所使用的$符号(拼接字符串)是C# 6.0引入的,其功能类似于string.Format()方法。
二、多线程、异步、同步之间的联系与区别
厨房案例:
比如说你要炒5道菜ABCDE,但是只有两个炉子可以用,即同时只能炒两道菜。在这里,炉子就是线程。
假如两个炉子分别同时炒A和B,那剩下的CDE只能等A或B炒完了才能开始。这个等待的过程就是同步,我们称之为阻塞,即这个时候你只能炒A和B这两道菜。
假如你还有一台咖啡机,在你炒A和B的时候顺手把咖啡豆和水放到咖啡机里打开开关,然后你就不用管它了。此时,就是新开了一个线程去煮咖啡,而煮咖啡
是由咖啡机自动完成的并不影响继续炒菜,所以煮咖啡这个线程是异步的,我们称之为非阻塞。
当咖啡机叮的一声通知你咖啡已经煮好了,你要去把咖啡拿出来加点糖或奶什么的,这个拿咖啡的动作我们称之为回调,这个是咖啡机线程完成之后通知你要去
做的动作。
简单来说:
会占用你的时间让你无法去做其它事情的任务叫做同步任务(炒菜要专注否则会糊锅)。
那些不需要占用你的时间的任务叫做异步任务(咖啡机自己会把咖啡煮好,不需要你一直看着它)。
下面代码演示不使用异步的情况:
class Program
{
//创建计时器
private static readonly Stopwatch stopwatch = new Stopwatch(); static void Main(string[] args)
{
#region async & await入门一之不使用异步
//启动计时器
stopwatch.Start();
//URL地址
const string url1 = "http://www.cnblogs.com/";
const string url2 = "http://www.cnblogs.com/atomy/";
//异步下载某网站内容,并统计字符的个数。
var result1 = CountCharacters("url1", url1);
var result2 = CountCharacters("url2", url2);
//主要是通过拼接字符串达到耗时操作
for (var i = ; i < ; i++)
{
ExtraOperation(i + );
}
//控制台输出
Console.WriteLine($"{url1} 的字符个数:{result1}");
Console.WriteLine($"{url2} 的字符个数:{result2}");
Console.WriteLine($"总耗时{stopwatch.ElapsedMilliseconds}ms。");
Console.Read();
#endregion
} /// <summary>
/// 统计字符个数
/// </summary>
/// <param name="id"></param>
/// <param name="address"></param>
/// <returns></returns>
private static int CountCharacters(string name, string address)
{
var wc = new WebClient();
Console.WriteLine($"{name}开始调用,历时{stopwatch.ElapsedMilliseconds}ms,线程id={Thread.CurrentThread.ManagedThreadId}。"); var result = wc.DownloadString(address);
Console.WriteLine($"{name}调用完成,历时{stopwatch.ElapsedMilliseconds}ms,线程id={Thread.CurrentThread.ManagedThreadId}。"); return result.Length;
} /// <summary>
/// 额外操作
/// </summary>
/// <param name="id"></param>
private static void ExtraOperation(int id)
{
//这里是通过拼接字符串进行一些相对耗时的操作
var s = "";
for (var i = ; i < ; i++)
{
s += i;
}
Console.WriteLine($"第{id}次ExtraOperation执行完成,历时:{stopwatch.ElapsedMilliseconds}ms。");
}
}
运行结果如下:

下面代码演示使用异步的情况:
class Program
{
//创建计时器
private static readonly Stopwatch stopwatch = new Stopwatch(); static void Main(string[] args)
{
#region async & await入门一之使用异步
//启动计时器
stopwatch.Start();
//URL地址
const string url1 = "http://www.cnblogs.com/";
const string url2 = "http://www.cnblogs.com/atomy/";
//异步下载某网站内容,并统计字符的个数。
Task<int> t1 = CountCharactersAsync("url1", url1);
Task<int> t2 = CountCharactersAsync("url2", url2);
//主要是通过拼接字符串达到耗时操作
for (var i = ; i < ; i++)
{
ExtraOperation(i + );
}
//控制台输出
Console.WriteLine($"{url1} 的字符个数:{t1.Result}");
Console.WriteLine($"{url2} 的字符个数:{t2.Result}");
Console.WriteLine($"总耗时{stopwatch.ElapsedMilliseconds}ms。");
Console.Read();
#endregion
} /// <summary>
/// 统计字符个数
/// </summary>
/// <param name="id"></param>
/// <param name="address"></param>
/// <returns></returns>
private static async Task<int> CountCharactersAsync(string name, string address)
{
var wc = new WebClient();
Console.WriteLine($"{name}开始调用,历时{stopwatch.ElapsedMilliseconds}ms,线程id={Thread.CurrentThread.ManagedThreadId}。"); var result =await wc.DownloadStringTaskAsync(address);
Console.WriteLine($"{name}调用完成,历时{stopwatch.ElapsedMilliseconds}ms,线程id={Thread.CurrentThread.ManagedThreadId}。"); return result.Length;
} /// <summary>
/// 额外操作
/// </summary>
/// <param name="id"></param>
private static void ExtraOperation(int id)
{
//这里是通过拼接字符串进行一些相对耗时的操作
var s = "";
for (var i = ; i < ; i++)
{
s += i;
}
Console.WriteLine($"第{id}次ExtraOperation执行完成,历时:{stopwatch.ElapsedMilliseconds}ms。");
}
}
运行结果如下:

三、async & await 结构
async & await结构可分成三部分:
1)调用方法:该方法调用异步方法,然后在异步方法执行其任务的时候继续执行。
2)异步方法:该方法异步执行工作,然后立刻返回到调用方法。
3)await表达式:用于异步方法内部,指出需要异步执行的任务。


四、异步方法
异步方法:在执行完成前立即返回调用方法,在调用方法继续执行的过程中完成任务。
语法分析:

参考自:
https://www.cnblogs.com/woxihuadabai/p/8042652.html
https://www.cnblogs.com/liqingwen/p/5831951.html
C#线程学习笔记八:async & await入门一的更多相关文章
- Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
- C#线程学习笔记九:async & await入门二
一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...
- C#线程学习笔记十:async & await入门三
一.Task.Yield Task.Yield简单来说就是创建时就已经完成的Task,或者说执行时间为0的Task,或者说是空任务,也就是在创建时就将Task的IsCompeted值设置为0. 我们知 ...
- Oracle RAC学习笔记:基本概念及入门
Oracle RAC学习笔记:基本概念及入门 2010年04月19日 10:39 来源:书童的博客 作者:书童 编辑:晓熊 [技术开发 技术文章] oracle 10g real applica ...
- Linux内核学习笔记-1.简介和入门
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- jQuery学习笔记 - 基础知识扫盲入门篇
jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...
- Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语
时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...
随机推荐
- (三)OpenStack---M版---双节点搭建---Keystone安装和配置
↓↓↓↓↓↓↓↓视频已上线B站↓↓↓↓↓↓↓↓ >>>>>>传送门 1.创建keystone数据库 2.创建随机密码作为管理员令牌 3.安装openstack-ke ...
- 【2018寒假集训 Day2】【动态规划】抢金块
抢金块 输入文件:gold.in 输出文件:gold.out 问题描述: 地面上有一些格子,每个格子上面都有金块,但不同格子上的金块有不同的价值,你一次可以跳S至T步 .如果S=2,T=4.你就可以跳 ...
- 在Spring Security框架下JWT的实现细节原理
一.回顾JWT的授权及鉴权流程 在笔者的上一篇文章中,已经为大家介绍了JWT以及其结构及使用方法.其授权与鉴权流程浓缩为以下两句话 授权:使用可信用户信息(用户名密码.短信登录)换取带有签名的JWT令 ...
- JSONPath入门之Snack3篇
Snack3 for java 一个微型JSON框架 基于jdk8,60kb.有序列化反序列化.解析和转换.支持 Json path 查询. <dependency> <groupI ...
- SpringMVC 前端传递list到后台
---恢复内容开始--- 1.前端获取传入后台的list 2.ajax写法: $.ajax({ type: 'post', url: url, async:false, dataType:" ...
- Flask入门学习——自定义一个url转换器
我们知道,flask的url规则是可以添加变量部分的,这个参数变量是写在尖括号里的,比如:/item/<id>/,如果需要指出参数的类型要符合<converter:vai ...
- JS获取当前完整的url地址以及参数的方法
javascript 获取当前 URL 参数的两种方法: //返回的是字符串形式的参数,例如:class_id=3&id=2& function getUrlArgStr(){ var ...
- element中 input赋值后无法再次输入值
项目中有个需求,在表格里点击某条数据弹出窗口进行修改值,当时弹出的是input上进行修改,所以当我点击数据的时候,先进行回显原先的数据,再进行修改. 点击某条数据,弹出窗口,进行后台请求,将后台返回的 ...
- VUE的中v-if和v-shou的区别
v-if的特点:每次都会重新删除或创建元素 v-shou的特点:每次执行都只是切换了元素的display:none的属性 v-if的缺点: 每次使用都会有较高性能消耗(频繁的切换元素建议不适用,建议使 ...
- Github Fork 缎带.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title&g ...