async 和 await 关键字只是编译器功能,编译器会用Task类创建代码。

返 回值是一个Task,这种返回新线程的方法虽然可以提高系统的响应能力,但是多线程取值会给编码带来不便,所以新出的关键字await用于阻塞当前线程并 获取目标线程的返回值,在方法体中使用await关键字后要求将方法声明为async用来表示该方法是异步的,并且返回值必须为void或者将返回者封装 在一个Task中

1、创建任务

  同步方法Greeting ,该方法等待一段时间后,返回一个字符串,通过GetHashCode 查看当前线程ID

代码如下:

        static string Greeting(string name){Task.Delay(3000).Wait();int j  = Task.CurrentId.GetHashCode();Console.WriteLine("name" + name);int i =Thread.CurrentThread.GetHashCode();Thread.Sleep(3000);Console.WriteLine("Task 的线程HASHCODE是: " + j);Console.WriteLine("Thread 的线程HASHCODE是" + i);Console.ReadLine();Thread.Sleep(3000);return $"Hello,{name}";}

定义方法GreetingAsync,可以使方法异步化,基于任务的异步模式指定,在异步方法名后加上Async后缀,并返回一个任务,异步方法GreetingAsync 和 同步方法Greeting具有相同的输入参数,但是异步方法返回的是Task<string>,Task<string> 定义了一个返回字符串的任务。代码如下所示:

        /// <summary>/// 异步调用方法/// </summary>/// <param name="name"></param>/// <returns></returns>static Task<string> GreetingAsync(string name){return Task.Run<string>(()=>{return Greeting(name);});}

2、调用异步方法

可以使用await 关键字来调用返回任务的异步方法GreetingAsync,使用await 关键字需要用async修饰符声明的方法,在GreetingAsync方法完成前,该方法内其他代码不会继续执行,但是启动

CallerWithAsync方法的线程可以被重用,该线程没有阻塞。

代码如下所示:

    class Program{static void Main(string[] args){CallerWithAsync();}/// <summary>/// 调用异步方法/// </summary>private async static void CallerWithAsync(){string result = await GreetingAsync("chenk");Console.WriteLine(result);}

3、延时任务

GreetingAsync 方法返回一个Task<string> 对象,对象包含任务创建的信息,并保存到任务完成,Task类的ContinueWith 方法定义了任何完成后就调用的代码,指派给ContinueWith方法的委托,将已完成的任务作为参数传入,使用Result属性,可以访问任务返回的结果。代码如下:

        /// <summary>/// 延续任务/// </summary>private static void CallerWithContinuationTask(){Task<string> t1 = GreetingAsync("chenk");//编译器把await 关键字后的代码放进ContinueWith 方法的代码块转换await关键字t1.ContinueWith(t =>{string result = t.Result;Console.WriteLine("CallerWithContinuationTask 线程Id :" + Thread.CurrentThread.GetHashCode() + "; result 的值为:" +result);Console.ReadLine();});}

4、同步上下文

验证方法中使用的线程,可以点击‘启动’——在‘调试’中选择‘线程’,即可查看当前异步程序运行的线程数及位置,以CallerWithContinuationTask为例,可以看到一个线程为主线程、一个线程在调用GreetingAsync方法、一个线程在执行ContinueWith方法内的代码堆。截图如下:

5、使用多个异步方法

5.1 按顺序调用多个异步方法

使用await 关键字可以调用每个异步方法,如果一个异步方法依赖于另一个异步方法的结果,await关键字就非常有用。

本例中,GreetingAsync 异步方法的第二次调用完全独立于第一次调用的结果,如果每个异步方法都不使用await,那么整个MultipleAsyncMethods异步方法将更快返回结果。代码如下:

        private async static void MutipleAsyncMethods(){string s1 = await GreetingAsync("chenk");string s2 = await GreetingAsync("zhangf");Console.WriteLine("Finished both methods \nResult 1:" + s1 + "\nResult 2:" + s2);Console.ReadLine();}

  5.2 使用组合器

如果异步方法不依赖于其他异步方法,则每个异步方法都不使用await ,而是把每个异步方法的返回结果赋值给Task变量,就会运行的更快,GreetingAsync方法返回Task<string>。这些方法现在可以并行执行了。

组合器可以帮助实现这一点,一个组合器可以接受多个同一类型的参数,并返回同一类型的值,多个同一类型的参数被组合成一个参数传递,Task组合器接受多个Task对象作为参数,并返回一个Task。

示例代码采用Task.WhenAll组合器方法,它可以等待,直到两个任务都完成。代码如下:

        /// <summary>/// 组合器 WhenAll/// </summary>private async static void MultipleAsyncMethodWithCombinatoral(){Task<string> t1 = GreetingAsync("chenk");Task<string> t2 = GreetingAsync("zhangf");//WhenAll 组合器,从WhenAll方法返回的Task,是在所有传入方法的任务都完成了才会返回Task。//WhenAny 组合器,是在其中一个传入方法的任务完成了就会返回Task。await Task.WhenAll(t1, t2);}/// <summary>/// 组合器WhenAll 重载,如果所有的任务返回相同的类型,那么该类型的数组可用于await返回的结果/// </summary>private async static void MultipleAsyncMethodWithCombinatoral2(){Task<string> t1 = GreetingAsync("chenk");Task<string> t2 = GreetingAsync("zhangf");string[] result = await Task.WhenAll(t1, t2);}

c#进阶(7)—— 异步编程基础(async 和 await 关键字)相关推荐

  1. 异步编程(async 和 await)

    1.概念 异步编程是一项关键技术,可以直接处理多个核心上的I/O阻塞和并发操作 2.使用场景 对于存在IO密集型(例如从网路请求数据.访问数据库和写入到文件系统)和CPU密集型(例如大量的计算)的任务 ...

  2. [进阶] --- Python3 异步编程详解(史上最全篇)

    [进阶] - Python3 异步编程详解:https://blog.csdn.net/lu8000/article/details/45025987 参考:http://aosabook.org/e ...

  3. [NodeJS]Node异步编程基础

    零.前言 为什么要用Node? Node把非阻塞IO作为提高应用性能的方式.而在JS中,天生拥有着异步编程机制: 事件机制.同时JS中不存在多进程.这样当你执行相对较慢需要花费时间长的IO操作时并不会 ...

  4. java socket 异步回调函数,分享nodejs异步编程基础之回调函数用法

    nodejs异步编程基础之回调函数用法分析 本文实例讲述了nodejs异步编程基础之回调函数用法.分享给大家供大家参考,具体如下: Node.js 异步编程的直接体现就是回调. 异步编程依托于回调来实 ...

  5. 【Flutter】Future 异步编程 ( 简介 | then 方法 | 异常捕获 | async、await 关键字 | whenComplete 方法 | timeout 方法 )

    文章目录 一.Future 简介 二.Future.then 使用 三.Future 异常捕获 四.Dart 练习网站 五.async.await 关键字 六.whenComplete 方法 七.ti ...

  6. 为什么我们要使用Async、Await关键字

    前不久,在工作中由于默认(xihuan)使用Async.Await关键字受到了很多质问,所以由此引发这篇博文"为什么我们要用Async/Await关键字",请听下面分解: Asyn ...

  7. 浅谈async、await关键字 = 深谈async、await关键字

    前言 之前写过有关异步的文章,对这方面一直比较弱,感觉还是不太理解,于是会花点时间去好好学习这一块,我们由浅入深,文中若有叙述不稳妥之处,还请批评指正. 话题 (1)是不是将方法用async关键字标识 ...

  8. [转][进阶]-Python3 异步编程详解

    目录 1 什么是异步编程 1.1 阻塞 1.2 非阻塞 1.3 同步 1.4 异步 1.5 并发 1.6 并行 1.7 概念总结 1.8 异步编程 1.9 异步之难(nán) 2 苦心异步为哪般 2. ...

  9. [进阶]-Python3 异步编程详解(史上最全篇)

    目录 1 什么是异步编程 1.1 阻塞 1.2 非阻塞 1.3 同步 1.4 异步 1.5 并发 1.6 并行 1.7 概念总结 1.8 异步编程 1.9 异步之难(nán) 2 苦心异步为哪般 2. ...

最新文章

  1. R语言使用ggplot2包的快速可视化函数qplot绘制散点图实战
  2. 关于Linux下s、t、i、a权限
  3. Spring Boot干货系列:(六)静态资源和拦截器处理 | 掘金技术征文
  4. Linux 用qmake快速生成makefile
  5. 042_CSS3字体
  6. ubuntu linux mac地址,Ubuntu下修改mac地址
  7. java中的方法在哪里_Java中的本机方法是什么,应在哪里使用?
  8. 【视频】Copula算法原理和R语言股市收益率相依性可视化分析
  9. 太阳影子定位问题研究
  10. [pion]测试你的TURN服务器
  11. 你还在用Rational Rose画图吗?来来来给你介绍一款开源免费上手容易的 BOUML UML画图工具。
  12. 计算机上word如何批量打印,批量打印文件夹中的多个Word文档
  13. linux下使用 sb接口扫描仪,怎样在Linux下设置和使用扫描仪.doc
  14. 国产化复旦微电子 FMQL45T900 FPGA开发板( 替代Xilinx ZYNQ ARM+FPGA 7045开发板)
  15. 钠离子电池翻红:“锂焦虑”之下的望梅止渴
  16. 5G物理信道个数和调制方式
  17. 爬虫的初步进阶||正则表达式+BeautifulSoup处理特殊标签实现多级网页跳转的信息爬取
  18. 直线一级倒立摆数学建模与控制仿真
  19. 乐学成语——数据库创建(导入、打开)
  20. springboot集成elasticsearch6.8.23设置密码xpack连接,及遇到的None of the configured nodes are available

热门文章

  1. Linux 监控数据库资源占用
  2. caffe生成voc格式lmdb
  3. cenos6.4安装gvim
  4. 【转】系统缓存全解析二:动态缓存(2)-页面局部缓存的两种方式
  5. [Leedcode][JAVA][第15题][三数之和][数组][双指针]
  6. [Leedcode][JAVA][第460题][LFU]
  7. 常见笔顺错误的字_最全汉字书写笔顺规则
  8. java垃圾回收机制_干货:Java 垃圾回收机制
  9. echarts 生成 迁徙图_echarts3 迁徙图 迁入迁出(示例代码)
  10. 线程启动语句的顺序是否决定线程的执行次序。_详细分析 Java 中启动线程的正确和错误方式