使用非异步方法调用可异步方法(内含嵌套异步)

效果图:

代码(在控制台mian函数中运行该函数):

        private static void AsyncTest(){Func<Task<string>> Fun1 = () =>{Thread.Sleep(4000); Console.WriteLine("Fun1 Open");return Task.Run(()=>{Thread.Sleep(2000);Console.WriteLine("Fun1 Run Open");Console.WriteLine("..............................");Thread.Sleep(5000);Console.WriteLine("..............................");Console.WriteLine("Fun1 Run Close");return "Fun1";}); }; Func<Task<string>> Fun2 = async () =>{Thread.Sleep(1000); Console.WriteLine("Fun2 Open"); var str2 = await Fun1(); Thread.Sleep(1000);Console.WriteLine("Fun1 Result "+ str2);Console.WriteLine("Fun2 Close"); return "Fun2";};Console.WriteLine("Asyn Open"); var str = Fun2();Console.WriteLine("Fun2 Result " + str); Console.WriteLine("Asyn Close");}

情景:

  1. 两个异步程序Fun2/Fun1
  2. Fun2使用(await)调用Fun1
  3. Fun2不使用异步调用

分析:

  1. 主线程执行过程中,遇到异步Fun2,执行同步过程,进入函数Fun2
  2. 函数Fun2执行过程中,遇到异步Fun1,执行异步过程await,进入Fun1
  3. 函数Fun1执行过程中,遇到异步时间Run,开启异步
  4. 主函数不等待异步,Fun1无返回值,输出Task对象
  5. 函数Fun2等待Fun1结果,再执行await后的语句

结论:

  1. 封装后的异步调用,如果被同步调用,应该使用void/Task无返回值方式
  2. await后的语句,相当于异步调用后的回调方法,写法更美观

使用await调用异步方法(嵌套异步)

代码:

var str = await Fun2();

在上文代码中Fun2函数前面加上await

效果图:

分析:

  1. 主线程执行过程中,遇到异步Fun2,执行异步过程await,进入函数Fun2
  2. 函数Fun2执行过程中,遇到异步Fun1,执行异步过程await,进入Fun1
  3. 函数Fun1执行过程中,遇到异步时间Run,开启异步
  4. 函数Fun2等待Fun1结果,再执行await后的语句
  5. 主函数等待Fun2结果,再执行await后的语句

结论:

  1. 要想达到嵌套异步的回调效果,每一个异步环节都要使用await标记分割

使用await调用异步方法(连续await)

效果图

代码:

Fun1添加参数p做区分,Fun2添加并行的await

            Func<string, Task<string>> Fun1 = (string p) =>{Thread.Sleep(4000); Console.WriteLine("Fun1 Open " + p);return Task.Run(()=>{Thread.Sleep(2000);Console.WriteLine("Fun1 Run Open " + p);Console.WriteLine("..............................");Thread.Sleep(5000);Console.WriteLine("..............................");Console.WriteLine("Fun1 Run Close " + p);return "Fun1 " + p;}); }; Func<Task<string>> Fun2 = async () =>{Thread.Sleep(1000); Console.WriteLine("Fun2 Open"); var str2 = await Fun1("No.1"); Thread.Sleep(1000);Console.WriteLine("Fun1 Result "+ str2);str2 = await Fun1("No.2");Thread.Sleep(1000);Console.WriteLine("Fun1 Result " + str2);Console.WriteLine("Fun2 Close"); return "Fun2";};

结论:

  1. 多个await并不会破坏await的“异步回调模式”
  2. 在上一个await执行回调后,下一个await作为回调函数内的语句继续执行await的过程
  3. 该语法糖很好吃,很强大的语法,拯救了键盘。

注意:

await异步回调的边界,是async所标记的函数的边界。其async函数内部的循环/判断等语句,都要服从与await的等待与回调过程。

C# async/awit 嵌套异步 执行顺序 分析相关推荐

  1. 详解promise、async和await的执行顺序

    说明: 本文摘自 详解 promise.async和await的执行顺序. 1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async func ...

  2. javascript的异步执行顺序---管中窥豹

    有一个经典例子: for (var i = 0; i < 10; i++) {setTimeout(function() { console.log(i); }, 100 * i); } 介绍一 ...

  3. mysql 执行顺序 SQL语句执行顺序分析

    最近在做一个数据库的大作业,算是复习了下MySql里面比较复杂的一些语句的用法,如Left Join之类的.在这里就不对具体语法进行记录了,希望能在以后经常用到,而不是隔好长时间用一次.在这里就记录下 ...

  4. MATLAB多个for循环嵌套的执行顺序、如何将生成的数据存放在一个向量或矩阵里?

    MATLAB中多个for循环嵌套的执行顺序: 当有两个for循环时,先执行一次外部for循环,再将内部循环全部执行. 当有三个for循环时,先执行一次最外部for循环,再执行一次第二层for循环,最后 ...

  5. SQL嵌套语句执行顺序

    首先我们要了解一下SQL语句的执行过程. SELECT 字段  FROM 表名  WHERE 条件表达式 那它们是按什么顺序执行呢?分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时 ...

  6. Ajax同步异步执行顺序问题

    今天项目中碰到一个问题,大概是这样的:JS中一个方法A需要先给隐藏域赋值,然后另一个方法B再从这个隐藏域取值,获取到这个值后给接口传参然后请求数据.也就是说这两个方法需要有执行顺序,A方法先执行,然后 ...

  7. 浅谈jQuery技术的ajax框架async同步和异步执行原理

    我们很多同学呀,不知道ajax框架async属性到底有什么作用,它在页面中的执行顺序到底是什么样的? 比如说我前端页面有以下几个方法: window.οnlοad= function charts() ...

  8. php 内部异步执行顺序,event_loop中不同异步操作的执行顺序

    关于js的单线程.怎么创建一个异步任务都是老生常谈的话题了,我们今天就总结一下js不同的异步操作到底执行顺序如何. 首先我们要明白js两种任务类型,一个是macrotask(宏任务),一个是 micr ...

  9. springMVC中拦截器执行时机和执行顺序分析

    1. 拦截器的作用时机 和过滤器一样,拦截器也可以拦截请求. 过滤器是在DispatcherServlet处理之前拦截,拦截器是在DispatcherServlet处理请求然后调用控制器方法(即我们自 ...

最新文章

  1. 2021全球抗体亲和力预测大赛来了!
  2. springboot2.4跨域配置的方法
  3. Linux中新建用户用不了sudo命令问题:rootr is not in the sudoers file.This incident will be reported解决
  4. mxnet输出训练loss
  5. HttpUrlConnection get和post简单实现(疑惑解决)
  6. Oracle:select into 查询没有记录的解决办法
  7. 简单快速导出word文档
  8. OAuth2.0授权协议的一个简单解释
  9. PHP Zend Studio9.0怎么把代码搞成和服务器端的同步(就是直接在服务器端修改)
  10. String,StringBuffer,StringBulilder之间的区别
  11. 一个商人骑一头驴要穿越1000公里长的沙漠,去卖3000根胡萝卜。已知驴一次性可驮1000根胡萝卜,但每走一公里又要吃掉一根胡萝卜。问:商人共可卖出多少胡萝卜? 答:533
  12. Hive实现数据文件导入与分析
  13. linux qt 找不到 lgl,c ++ - Qt:找不到-lGL
  14. halcon相机标定助手_halcon相机标定和图像矫正
  15. 小白上班摸鱼学python
  16. Android Studio报错:NDK does not contain any platforms
  17. troublemaker中文谐音_张贤胜 金泫雅-Trouble Maker中文谐音的歌词
  18. android自定义button样式【转】
  19. 乘风破浪会有时,直挂云帆济沧海
  20. JAVA获取当前时间(yyyy-MM-dd HH:mm:ss)

热门文章

  1. 电驱动系列:十七、相绕组的磁势、分布系数、绕组系数及齿谐波(电机篇)
  2. 【排序】 挖坑快排图解
  3. DataReader和DataSet的异同
  4. java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY报错
  5. JS章节 第一节总结知识点
  6. [数值计算-19]:万能的任意函数的数值求导数方法
  7. BERT_中文情感分类操作及代码
  8. 水仙花数(3位水仙花、100-999之内的所有水仙花、三位及以上水仙花)
  9. R型电源变压器的选材和设计有什么讲究?
  10. 7-16 九宫格输入法(15 分)