一、涉及内容

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表达式:用于异步方法内部,指出需要异步执行的任务。

四、异步方法

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

语法分析:

    1)关键字:方法头返回类型前使用async关键字,它是一个上下文关键字。
    2)要求:需有await表达式(可多个)方可进行异步操作,否则视为普通方法进行同步操作。
    3)返回类型:只能返回3种类型(void、Task和Task<T>)。Task和Task<T>标识返回的对象会在将来完成工作,表示调用方法和异步方法可以继续执行。
    4)参数:数量不限,但不能使用out和ref关键字。
    5)命名约定:方法后缀名应以Async结尾。
    6)其它:匿名方法和 Lambda 表达式也可以作为异步对象。

    参考自:

https://www.cnblogs.com/woxihuadabai/p/8042652.html

https://www.cnblogs.com/liqingwen/p/5831951.html

C#线程学习笔记八:async & await入门一的更多相关文章

  1. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  2. C#线程学习笔记九:async & await入门二

    一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...

  3. C#线程学习笔记十:async & await入门三

    一.Task.Yield Task.Yield简单来说就是创建时就已经完成的Task,或者说执行时间为0的Task,或者说是空任务,也就是在创建时就将Task的IsCompeted值设置为0. 我们知 ...

  4. Oracle RAC学习笔记:基本概念及入门

    Oracle RAC学习笔记:基本概念及入门 2010年04月19日 10:39 来源:书童的博客 作者:书童 编辑:晓熊 [技术开发 技术文章]    oracle 10g real applica ...

  5. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. jQuery学习笔记 - 基础知识扫盲入门篇

    jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...

  8. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  9. 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语

    时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...

随机推荐

  1. Spring中的事务回滚机制

    初学者笔记 问题:在Java项目汇中,添加@Transactional注解,报错之后,事务回滚未生效,数据仍插入数据库中.经查看报错位置位于新增成功之后.空指针异常. 一.特性 先了解一下@Trans ...

  2. Stream系列(三) FlatMap方法使用

    将多维嵌套列表转换为单维列表 EmployeeTestCase.java package com.example.demo; import lombok.Data; import lombok.ToS ...

  3. 记一次uboot中gunzip解压速度慢的问题排查

    背景 在项目中需要用到解压功能,之前还记录了下,将uboot解压代码移植到另外的bootloader中时,碰到的效率问题.最终查明是cache的配置导致的. https://www.cnblogs.c ...

  4. 解决配置vim中文乱码的问题

    解决linux下vim乱码的情况:(修改vimrc的内容) 全局的情况下:即所有用户都能用这个配置 文件地址:/etc/vimrc 在文件中添加: set fileencodings=utf-8,uc ...

  5. Git同步本地项目文件到github

    1.登录自己的github账号,并创建一个存放项目代码的仓库 输入仓库名称后,点击create,然后来到完成后的页面,copy下以下内容,后面会用到 2.打开本地的git 安装好git后,打开git的 ...

  6. JAVA中字符串常见操作

    String str1="hello,world";String str2="Hello,World"; 1.字符串的比较:例,System.out.print ...

  7. flanneld 安装

    目录 flanneld 安装 下载分发flanneld二进制文件 分发二进制文件到所有集群的节点 创建Flannel证书和私钥 创建证书签名请求 生成证书和私钥 向etcd写入Pod网段信息 创建fl ...

  8. NetScaler内网外网ip映射的配置

  9. mac安装jupyter

    SaintKings-Mac-mini:.pip saintking$ pip install jupyter --user Collecting jupyter Downloading jupyte ...

  10. 第五章 Unity中的基础光照(3)

    目录 1. 在Unity Shader中实现高光反射光照模型 1.1 实践:逐顶点光照 1.2 逐像素光照 1.3 Blinn-Phong光照模型 2. 召唤神龙:使用Unity内置的函数 @ 1. ...