网上关于async/await的知识有很多,看了很多但不如自己实践一遍来得快,所以这里记录下我的理解和大家学习下。

首先以最简单的同步方法来开始如下

 private static   void Test()
{ Console.WriteLine();
GetV();
Console.WriteLine();
}
private static void GetV()
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
} static void Main(string[] args)
{ Console.WriteLine();
Test();
Console.WriteLine();
}

输出如下

当时当我们简单的使用Task.Run时

  private static   void Test()
{ Console.WriteLine(2);
GetV();
Console.WriteLine(6);
}
private static void GetV()
{
Console.WriteLine(3);
Task.Run(() =>
{
Thread.Sleep(10000);
Console.WriteLine(4);
});
Console.WriteLine(5);
} static void Main(string[] args)
{ Console.WriteLine(1);
Test();
Console.WriteLine(7);
}

  

,因为分配了新的线程,所以4会最晚打印出来。

这时候我们使用async/await呢?

 private static async Task Test()
{ Console.WriteLine();
await GetV();
Console.WriteLine();
}
private static async Task GetV()
{
Console.WriteLine();
await Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine();
});
Console.WriteLine(); } static void Main(string[] args)
{ Console.WriteLine();
var v= Test();
Console.WriteLine();
}

因为await会时被修饰的代码处于等待状态,就相当于阻塞那段代码,Test方法里面执行到await时就会等待Getv的方法的执行,就会阻塞Test方法,但是不会阻塞Main方法,可以理解为await将阻塞的控制权交给了Test方法。所以这个时候打印结果为

但是当我们把Test的await去掉了,这时候Test方法就没有了阻塞的权限,而是去寻找下一个await来转移控制权,如下

   private static void Test()
{ Console.Out.WriteLine();
GetV();
Console.Out.WriteLine();
}
private static async Task GetV()
{
Console.Out.WriteLine();
await Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine();
});
Console.Out.WriteLine(); } static void Main(string[] args)
{ Console.Out.WriteLine();
Test();
Console.Out.WriteLine();
string str = Console.ReadLine();
}

这个时候就不会阻塞Test方法,结果如下

如果在main方法里面使用Task.GetAwaiter或者Task.Result呢,这两个东西我的理解就是阻塞线程,等待异步返回结果,但是它阻塞的是当前的方法,如下代码

        private static async Task Test()
{ Console.Out.WriteLine();
GetV();
Console.Out.WriteLine();
}
private static async Task GetV()
{
Console.Out.WriteLine();
await Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine();
});
Console.Out.WriteLine(); } static void Main(string[] args)
{ Console.Out.WriteLine();
Test().GetAwaiter().GetResult() ;
Console.Out.WriteLine();
string str = Console.ReadLine();
}

它只会阻塞main方法的,但是对于Test方法它是无法阻塞的,Test方法仍然会异步执行,4,5仍然以异步的方法打印出来,所以打印结果如下

Task.Result也是如此,只会阻塞当前的方法,我觉得和await相似,只给了当前使用Task.GetAwaiter或者Task.Result的方法阻塞全,没有权利阻塞别的方法。

打个广告:游戏也能赚钱?如果你热爱游戏,并且想通过游戏赢得零花钱,5173是个不错的选择  http://www.5173.com/?recommenduserid=US15061749098191-04F6

初步学习async/await,Task.GetAwaiter,Task.Result的更多相关文章

  1. JavaScript基础——深入学习async/await

    本文由云+社区发表 本篇文章,小编将和大家一起学习异步编程的未来--async/await,它会打破你对上篇文章Promise的认知,竟然异步代码还能这么写! 但是别太得意,你需要深入理解Promis ...

  2. 七 vue学习 async/await

    1:  javaScript async/await: 调用async函数的时候,是异步的,函数后面的代码继续执行.! async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解 ...

  3. async await task.Result 卡死

    在如下代码中: public async Task<string> GetData() { return await DoWork(); } 在UI线程中调用 var data = Get ...

  4. C#多线程和异步(二)——Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  5. C#多线程和异步(二)——Task和async/await详解(转载)

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  6. Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  7. C#多线程和异步——Task和async/await详解

    阅读目录 一.什么是异步 二.Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 3 Task的延续操作(WhenAny/WhenAll/Cont ...

  8. 浅析C#中的Thread ThreadPool Task和async/await

    .net 项目中不可避免地要与线程打交道,目的都是实现异步.并发.从最开始的new Thread()入门,到后来的Task.Run(),如今在使用async/await的时候却有很多疑问. 先来看一段 ...

  9. .net 异步编程async & await关键字的思考

    C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的asy ...

随机推荐

  1. navicat mysql 书写存储过程并导出成sql

    navicat创建存储过程: 选中该数据库 然后完成,保存的时候出错: 需要为字段类型添加类型的大小.下面加一下. 然后就在这里面写相关的业务代码了. 语句结尾需要加上分号;  .否则会报错. 这边展 ...

  2. 并发编程(五)--GIL、死锁现象与递归锁、信号量、Event事件、线程queue

    一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的 ...

  3. linux常见性能分析工具

     vmstat    sar  (来源于sysstat工具包,需要yum  sysstat)iostat  (来源于sysstat工具包,需要yum  sysstat)free  -muptimene ...

  4. 性能测试基础---jmeter基础

    ·Jmeter的脚本构成: Jmeter的脚本是由很多不同的组件构成,在Jmeter中,组件可以分为以下几类: ·测试计划: 是默认存在的组件,所有的Jmeter的组件都是依赖于测试计划的. 在这个组 ...

  5. 学习:CC断点

    断点介绍: shark恒老师说有四种说法,但是其实都是相同的 第一个读法:普通断点 第二个读法:F2断点 第三个读法:INT3断点( int3其实就是汇编指令 ) 第四个读法:CC断点 (CC其实就是 ...

  6. python--协程知识初识

    线程和进程的操作是由程序触发系统接口,最后的执行者是系统:协程的操作则是程序员. 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续).协程 ...

  7. LeetCode 528. Random Pick with Weight

    原题链接在这里:https://leetcode.com/problems/random-pick-with-weight/ 题目: Given an array w of positive inte ...

  8. es4x 引用外部jar 包以及集成typescrip

    以前写过一个通过修改jar 包处理自定义jar 的引入的,如下是一种使用官方推荐的方法package.json 添加依赖配置 同时为了方便使用添加typescript define 文件方便使用(只是 ...

  9. [RN] React Native 权限申请 react-native-permissions

    React Native 权限申请 react-native-permissions 一.安装 npm i -S react-native-permissions link: react-native ...

  10. 简要说明盒子模型和flex布局

    盒子模型:可以看做是一个盒子,包括外边距.边框.内边距.实际内容. flex布局:弹性布局,灵活性好. 当给元素设置display:flex时,它就是flex容器,它的所有子元素自动成为容器成员,称为 ...