异步async与await的简单探究
在学习.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的简单探究的更多相关文章
- C# 异步编程,async与await的简单学习
前提声明:C# 5.0 .NET Framework 4.5 2012-08-15 异步和等待(async和await).调用方信息(Caller Information) (C#版本与.NET版本 ...
- 异步async、await和Future的使用技巧
由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果.Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞, ...
- flutter 异步async、await和Future的使用技巧
由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果.Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞, ...
- .Net 4.5 的async 和await 的简单理解使用
原文地址:http://www.cnblogs.com/HJL-Blog/p/4432632.html 所谓的异步编程是利用CPU空闲时间和多核的特性,它所返回的Task或Task<TResul ...
- 异步async/await简单应用与探究
感谢Marco CAO指出的两点错误,已做出修改与补充 异步函数(async/await)简单应用 .NET Framework4.5提供了针对异步函数语法糖,简化了编写异步函数的复杂度. 下面通过一 ...
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
- 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- 四、C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...
随机推荐
- python读取excel,返回dic列表
def get_xls_sheets_as_dic(pro_name, xls_name): dic_list = [] xls_path = os.path.join(BASE_PATH, &quo ...
- springboot 开启事务以及手动提交事务
添加依赖,sprongboot 会默认开启事务管理 org.springframework.boot spring-boot-starter-jdbc 在需要的服务类里添加注解 @Autowired ...
- JAVA设计方法思考之如何实现一个方法执行完毕后自动执行下一个方法
今天编程时,突然想起来在一些异步操作或Android原生库的时候,需要我们实现一些方法, 这些方法只需要我们具体实现,然后他们会在适当的时候,自动被调用! 例如AsyncTask,执行玩doInBac ...
- 【译】在Transformer中加入相对位置信息
目录 引言 动机 解决方案 概览 注释 实现 高效实现 结果 结论 参考文献 本文翻译自How Self-Attention with Relative Position Representation ...
- linux 之 shell
echo 输出命令 语法:echo [选项][输出内容] 选项 -e:支持反斜线控制的字符转换 范例 vi hello.sh #!/bin/bash #author liuch echo " ...
- maven+springMVC+mybatis+sqlserver数据
因为之前搭好的是maven+springMVC+mybatis+mysql数据库环境,但是在实际工作项目是使用的sqlserver数据库,本文是针对数据库从mysql切换到sqlserver数据库 s ...
- Spring Boot与Docker部署
开启Docker远程访问 首先需要开启docker远程访问功能,以便可以进行远程操作. CentOS 6 修改/etc/default/docker文件,重启后生效(service docker re ...
- 爬虫之Splash
Splash 是一个JavaScript渲染服务,是一个带有HTTP API 的轻量级浏览器,同时它对接了Python中Twisted和QT库. 1.功能介绍 1)异步方法处理多个网页渲染过程: 2) ...
- word里如何将模板的样式(标题啊、字体啊)导入到另外的模板里
点进去
- SpringCloud-day07-Feign
7.Feign 7.1.Feign简介 声明式服务调用Feign简单介绍下: Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单.我们只需要使用F ...