aync await 进一步探索

首先来个例子

class Program
{
static int index = 1;
static void Log(string str)
{
Console.WriteLine((index++) + ". " + str + ". ThreadId:" + Thread.CurrentThread.ManagedThreadId);
} static void Main(string[] args)
{
//解决.net core控制台输出中文乱码的代码
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//async 不能用于Main方法,所以在这里单独使用一个方法来调用,各位可以试试,编译不过,但VS就是不会告诉你错误在哪里
ExcuteAsync();
Console.ReadLine();
} static async void ExcuteAsync() {
Log("异步方法调用前");
var ret = AsyncMethod();
Log("异步方法调用后");
Log(await ret);
Log("异步方法使用await后");
} static async Task<string> AsyncMethod() {
Log("异步方法开始");
var task = Task.Run<string>(() =>
{
Log("异步方法内部开始");
Thread.Sleep(3000);
Log("异步方法内部结束");
return "来自异步方法内部的结果";
});
Log("异步方法结束");
var ret = await task;
Log("异步方法await结束");
return ret;
}
}

控制台输出结果

1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法调用后. ThreadId:1
6. 异步方法内部结束. ThreadId:3
7. 异步方法await结束. ThreadId:3
8. 来自异步方法内部的结果. ThreadId:3
9. 异步方法使用await后. ThreadId:3

分析

为了描述更方便,为每条输出都添加了序号。 为了更清晰的知道每一步的执行顺序以及所在的线程,均添加了ThreadId

  1. 第1条输出,主线程,没有什么特别的。
  2. 第2条输出,主线程,说明:调用异步方法本身并不会另起一个线程,如果这里面没有await的话,调用这个方法和调用普通方法没有任何区别。
  3. 第3条输出,主线程,说明:执行异步方法后主线程并没有被挂起,而是直接继续往下走。
  4. 第4条输出,线程3(代表子线程,不一定每次都是3),代码显示的要起用一个新线程,没有什么特别的。
  5. 第5条输出,主线程,和第3条一样,主线程继续往下走,只是代码在不同的方法里而已。
  6. 第6条输出,线程3,内部执行结束,没什么特别。
  7. 第7条输出,线程3,说明:这里有一个不同的地方,使用了await,可见,这里是子线程的延续
  8. 第8-9条输出,线程3,和第7条一样,延续了子线程。

变种

我们把ExcuteAsync方法里的await ret,改成ret.Result看看效果

1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法调用后. ThreadId:1
6. 异步方法内部结束. ThreadId:3
7. 异步方法await结束. ThreadId:3
8. 来自异步方法内部的结果. ThreadId:1
9. 异步方法使用await后. ThreadId:1

第8-9条输出线程变了,可见是主线程被挂起了,等待子线程结束后继续往下执行。那么如果在AsyncMethod里也使用Result,效果又是什么样的?

我们把AsyncMethod方法里的await task改成task.Result,看输出结果

1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法内部结束. ThreadId:3
6. 异步方法await结束. ThreadId:1
7. 异步方法调用后. ThreadId:1
8. 来自异步方法内部的结果. ThreadId:1
9. 异步方法使用await后. ThreadId:1

现在只有Task内部的输出是在子线程了。可见,使用Result的话会失去异步的效果,换句话说,使用Result就不再是异步调用了

附:文笔不好,只能用习惯的代码来描述,希望能给读者带来帮助。

aync await 进一步探索的更多相关文章

  1. Celery:进一步探索

    一.创建Celery专用模块 对于大型项目,一般需要创建一个专用模块,便于管理. 1.1 模块结构 proj/__init__.py /celery.py /tasks.py proj/celery. ...

  2. 进一步探索:Windows Azure 网站中解锁的配置选项

     编辑人员注释: 本文章由 Windows Azure 网站团队的项目经理 Erez Benari 撰写. 在 Windows Azure 网站 (WAWS) 中管理网站时,许多选项可使用 Azu ...

  3. Python标准库11 多进程探索 (multiprocessing包)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在初步了解Python多进程之后,我们可以继续探索multiprocessing包 ...

  4. c#之Async、Await剖析

    c#之Async.Await剖析 探索c#之Async.Await剖析 2015-06-15 08:35 by 蘑菇先生, 1429 阅读, 5 评论, 收藏, 编辑 阅读目录: 基本介绍 基本原理剖 ...

  5. [转] Async/Await替代Promise的6个理由

    Node.js 7.6已经支持async/await了,如果你还没有试过,这篇博客将告诉你为什么要用它. Async/Await简介 对于从未听说过async/await的朋友,下面是简介: asyn ...

  6. Hadoop2源码分析-RPC探索实战

    1.概述 在<Hadoop2源码分析-RPC机制初识>博客中,我们对RPC机制有了初步的认识和了解,下面我们对Hadoop V2的RPC机制做进一步探索,在研究Hadoop V2的RPC机 ...

  7. 每一行代码都有记录—如何用git一步步探索项目的历史

    每一行代码都有一块被隐藏了的文档信息. 下面的代码片段不管是谁写的,其第4行因为某些原因要访问一个DOM结点的clientLeft属性,但却对结果不作任何处理.这十分的莫名其妙,你能告诉我他们为什么要 ...

  8. 企查查app 初步探索

    企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 已删除!!!! 上边一些变量已经找到了,其中就有时间戳,其余两个需要 ...

  9. python_lesson2 多进程探索 (multiprocessing包)

    进程池 进程池 (Process Pool)可以创建多个进程.这些进程就像是随时待命的士兵,准备执行任务(程序).一个进程池中可以容纳多个待命的士兵.       import multiproces ...

随机推荐

  1. css删除线,下划线等

    <style> .p1 { text-decoration:overline; //上划线 } .p2 { text-decoration:line-through; //删除线 }  . ...

  2. Google永远不可能回到国内,只能是回忆

    今天早上在微博上无意看 [谷歌翻译App在大陆地区恢复无障碍使用]这篇文章,不知不觉就点进去看一下,内心还是比较兴奋,为什么兴奋说不清楚.或许我们是真的喜欢Google的产品. 回想2010年Goog ...

  3. 20155215 2016-2017-2 《Java程序设计》第5周学习总结

    学号 2006-2007-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 尝试捕捉错误对象,try,catch. 如何抛出错误对象,throw语法. error代表系统错 ...

  4. GCM(Google Cloud Messaging)推送完全解析

    应该是目前为止全网最详细的GCM推送解析. GCM官方解释: https://developers.google.cn/cloud-messaging/?hl=zh-cn Send data from ...

  5. 持续集成:TestNG中case之间的关系

    持续集成:TestNG中case之间的关系   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...

  6. 性能测试分享:Jmeter的api监控工具解决方案

    性能测试分享:Jmeter的api监控工具解决方案 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询q ...

  7. Angular4.0.0发布总览文章

    翻译自angular.io上的关于4.0.0版本发布的文章,内容主要是介绍了4.0.0版本下的改进以及接下来还会有的其他更新,4.0.0其实已经出来好多天了,截止目前都已经到了4.0.1版本了,这也是 ...

  8. JavaScript高级程序设计---学习笔记(四)

    1.全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以. var age = 29; window.color = "red"; delete age ...

  9. 通过一个小游戏开始接触Python!

    之前就一直嚷嚷着要找视频看学习Python,可是一直拖到今晚才开始....好好加油吧骚年,坚持不一定就能有好的结果,但是不坚持就一定是不好的!! 看着视频学习1: 首先,打开IDLE,在IDLE中新建 ...

  10. CI Weekly #17 | flow.ci 支持 Java 构建以及 Docker/DevOps 实践分享

    这周一,我们迫不及待写下了最新的 changelog -- 项目语言新增「Java」.创建 Java 项目工作流和其它语言项目配置很相似,flow.ci 提供了默认的 Java 项目构建流程模版,快去 ...