在学习.net core的过程中,到处见到异步的使用,Task、async、await随处可见。有点疑惑,就去了解了下这个过程是怎样的。

下面是一段代码,去看看是怎么执行的吧。

一、看看异步执行的方式

static void Main(string[] args)
{   Console.WriteLine("我是主线程:我的ID是:" + Thread.CurrentThread.ManagedThreadId);
  Console.WriteLine();   TestAsync();   Console.WriteLine("不等异步完成我先执行了哈,我的ID是:" + Thread.CurrentThread.ManagedThreadId);
  Console.ReadKey(); }
/// <summary>
/// 异步方法
/// </summary>
/// <returns></returns>
static async Task TestAsync()
{
Console.WriteLine("我是TestAsync,调用我的线程ID是:" + Thread.CurrentThread.ManagedThreadId);
await Task.Run(() => {
  Console.WriteLine("我是在TestAsync中开启的线程,ID是:" + Thread.CurrentThread.ManagedThreadId);
});
Console.WriteLine("TestAsync开启的线程执行完后,此时的线程ID为:" + Thread.CurrentThread.ManagedThreadId);
}

  我们看到,主线程ID是1,然后调用TestAsync方法,注意在Main方法中,调用TestAsync我们没有使用await,因为在Main方法中不支持async。

主线程调用TestAsync方法,进到TestAsync之后,打印出调用TestAsync方法的线程的ID。然后遇到Task.Run开启新的线程,ID为3。Task.Run之前有await,

注意:await会阻塞当前线程,就是ID为3的线程,并且释放调用TestAsync方法的线程,也即是主线程(ID为1),这个时候我们看到"不等异步完成我先执行了哈,我的ID是:1"

输出在"TestAsync开启的线程执行完后,此时的线程ID为:4"之前。这就说明了,TestAsync方法中await释放了主线程,同时Task.Run开启了一个新的线程。

Task.Run开启的线程是从线程池中取出的空闲线程。我运行几次,发现最后一个输出的结果不一样。如下图:

这应该说明,Task.Run开启线程后,await后的代码,是会重新开启一个线程去执行的。

二、看看await是怎么阻塞之后的代码的。

static void Main(string[] args)
{   Console.WriteLine("我是主线程:我的ID是:" + Thread.CurrentThread.ManagedThreadId);
  Console.WriteLine();   TestAsync();   Console.WriteLine("不等异步完成我先执行了哈,我的ID是:" + Thread.CurrentThread.ManagedThreadId);
  Console.ReadKey(); }
/// <summary>
/// 异步方法
/// </summary>
/// <returns></returns>
static async Task TestAsync()
{
Console.WriteLine("我是TestAsync,调用我的线程ID是:" + Thread.CurrentThread.ManagedThreadId);
await TestAsync2();
Console.WriteLine("我被阻塞了,在TestAsync2执行之后才会执行,现在的线程ID是:" + Thread.CurrentThread.ManagedThreadId);
await Task.Run(() => {
Console.WriteLine("我是在TestAsync中开启的线程,ID是:" + Thread.CurrentThread.ManagedThreadId);
});
Console.WriteLine("TestAsync开启的线程执行完后,此时的线程ID为:" + Thread.CurrentThread.ManagedThreadId);
}
static async Task TestAsync2()
{
Console.WriteLine();
Console.WriteLine("我是TestAsync2,调用我的线程ID是:" + Thread.CurrentThread.ManagedThreadId);
await Task.Run(() => {
Console.WriteLine("我是在TestAsync2中开启的线程,ID是:" + Thread.CurrentThread.ManagedThreadId);
int num = ;
for (int i = ; i < ; i++)
{
num += ;
}
Console.WriteLine($"在TestAsync2中执行一个耗点儿时间的操作,num的值是{num}");
});
}

我们看到在TestAsync中调用TestAsync2前面加了await,"我被阻塞了,在TestAsync2执行之后才会执行,现在的线程ID是:3"

在TestAsync2方法执行之后,才输出。并且这个时候主线程被释放掉了,去输出"不等异步完成我先执行了哈,我的ID是:1"。

好了,暂时就理解了这么多,肯定有不对的地方,欢迎大家指正,时间不早了,早点休息,做个佛系养生的程序员,

异步async与await的简单探究的更多相关文章

  1. C# 异步编程,async与await的简单学习

    前提声明:C# 5.0 .NET Framework 4.5 2012-08-15 异步和等待(async和await).调用方信息(Caller Information)  (C#版本与.NET版本 ...

  2. 异步async、await和Future的使用技巧

    由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果.Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞, ...

  3. flutter 异步async、await和Future的使用技巧

    由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果.Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞, ...

  4. .Net 4.5 的async 和await 的简单理解使用

    原文地址:http://www.cnblogs.com/HJL-Blog/p/4432632.html 所谓的异步编程是利用CPU空闲时间和多核的特性,它所返回的Task或Task<TResul ...

  5. 异步async/await简单应用与探究

    感谢Marco CAO指出的两点错误,已做出修改与补充 异步函数(async/await)简单应用 .NET Framework4.5提供了针对异步函数语法糖,简化了编写异步函数的复杂度. 下面通过一 ...

  6. 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...

  7. 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  8. [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  9. 四、C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...

随机推荐

  1. python大法好——Python SMTP发送邮件

    Python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. py ...

  2. idea使用

    一.IDEA 的下载及安装 打开IDEA的官网,如:http://www.jetbrains.com/ 然后到了主界面,点击下载如图:   图1 我们这里下载zip的,将它下载到你要保存的目录下,其次 ...

  3. java idea 代码规范插件

    推荐阿里的 p3c https://github.com/alibaba/p3c

  4. 使用 nodeJs 开发微信公众号(获取access_token)

    要使用微信提供的功能接口,就需要获取到access_token,这是开发公众号必不可少的一部 access_token有效期20分钟,建议保存起来,过期后在重新获取 获取流程如下: 我将微信相关的操作 ...

  5. Vue组件间传值 v-model

    使用过Vue的同学应该都了解组件之间传值 父组件 --> 子组件 : props 子组件 --> 父组件 : 事件 其实有一种更为简单的方法,是基于上述两种方法,那就是 v-model 我 ...

  6. hbase版本升级的api对比

    前言 今天来介绍一下,hbase的2.1.0版本升级之后和1.2.6版本的api方法的一些不同之处. hbase的工具类 在介绍hbase的相关的java api之前,这里先介绍一下hbase的工具类 ...

  7. urllib、urllib2、urllib3区别和使用

    python3中把urllib和urllib合并为一个库了,urllib对应urllib.request 1.) python 中最早内置拥有的网络请求模块就是 urllib,我们可以看一下 urll ...

  8. ORM项目中小知识点积累

    申明:一下内容均建立在零基础小白的角度上,大佬们求放过~ 1.如何通过类建立外键关联 2.模板语言固定搭配 3.浏览器报错处理 4.后台取值方式 5.外键管理修改相关操作 6.两种(给后台偷偷传递消息 ...

  9. 1.Sed | Awk | Grep | Find

    1.Sed | Awk | Grep | Find 可以参考的文档链接 CentOS7 查看 当前机器 已经启动的端口的Shell命令: netstat -lntup | awk -F' ' {'pr ...

  10. elk报警监控之sentinl 钉钉+邮件告警

    注:我的elk sentinl版本都是6.5.1 前期知识 es的查询语法.es watcher使用方法. https://www.cnblogs.com/pilihaotian/p/5830754. ...