一. async和await简介

PS:简介

1. async和await这两个关键字是为了简化异步编程模型而诞生的,使的异步编程跟简洁,它本身并不创建新线程,但在该方法内部开启多线程,则另算。

2. 这两个关键字适用于处理一些文件IO操作。

3. 好处:代码简介,把异步的代码写成了同步的形式,提高了开发效率。

 坏处:如果使用同步思维去理解,容易出问题,返回值对不上。

二. 几种用法

情况1:当只有async,没有await时,方法会有个警告,和普通的多线程方法没有什么区别,不存在线程等待的问题。

代码实践:

  1. private static async void Test1()
  2. {
  3. //主线程执行
  4. Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  5. //启动新线程完成任务
  6. Task task = Task.Run(() =>
  7. {
  8. Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  9. Thread.Sleep();
  10. Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  11. });
  12. //主线程执行
  13. Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  14. }

代码结果:

情况2:不推荐void返回值,使用Task来代替Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。

代码实践:

  1. /// <summary>
  2. /// 不推荐void返回值,使用Task来代替
  3. /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。async Void 不行
  4. /// </summary>
  5. private static async void Test2()
  6. {
  7. //主线程执行
  8. Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  9. //启动新线程完成任务
  10. Task task = Task.Run(() =>
  11. {
  12. Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  13. Thread.Sleep();
  14. Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  15. });
  16. await task; //等待子线程执行完毕,方可执行后面的语句
  17. Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  18. }

代码结果:

情况3:async Task == async void。 区别:Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。

代码实践:

  1. /// <summary>
  2. /// 无返回值 async Task == async void
  3. /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行
  4. /// </summary>
  5. private static async Task Test3()
  6. {
  7. //主线程执行
  8. Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  9. //启动新线程完成任务
  10. Task task = Task.Run(() =>
  11. {
  12. Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  13. Thread.Sleep();
  14. Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  15. });
  16. await task; //等待子线程执行完毕,方可执行后面的语句
  17. Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  18. }

代码结果:

情况4和情况5:说明要使用子线程中的变量,一定要等子线程执行结束后再使用。

代码实践:

  1. /// <summary>
  2. /// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行
  3. /// </summary>
  4. /// <returns></returns>
  5. private static async Task<long> Test4()
  6. {
  7. //主线程执行
  8. Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  9. long result = ;
  10. //启动新线程完成任务
  11. Task task = Task.Run(() =>
  12. {
  13. for (long i = ; i < ; i++)
  14. {
  15. result += i;
  16. }
  17. });
  18. await task; //等待子线程执行完毕,方可执行后面的语句
  19. Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  20. Console.WriteLine("result:{0}", result);
  21. return result;
  22. }
  1. /// <summary>
  2. /// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行
  3. /// 与情况四形成对比,没有等待,最终结果不准确
  4. /// </summary>
  5. /// <returns></returns>
  6. private static Task<long> Test5()
  7. {
  8. //主线程执行
  9. Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
  10. long result = ;
  11. //启动新线程完成任务
  12. TaskFactory taskFactory = new TaskFactory();
  13. Task<long> task = taskFactory.StartNew<long>(() =>
  14. {
  15. for (long i = ; i < ; i++)
  16. {
  17. result += i;
  18. }
  19. return ;
  20. });
  21. Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
  22. Console.WriteLine("result:{0}", result);
  23. return task;
  24. }

代码结果:

  以上两种情况,第一种情况含有线程等待的结果为4950,第二个情况么有线程等待,结果不准确(即共享变量竞用问题)。

第十节:利用async和await简化异步编程模式的几种写法的更多相关文章

  1. 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]

    看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...

  2. 使用Async和Await进行异步编程(C#版 适用于VS2015)

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  3. 使用Async和Await进行异步编程(C#版 适用于VS2015) z

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  4. Async和Await进行异步编程

    使用Async和Await进行异步编程(C#版 适用于VS2015) 你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很 ...

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

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

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

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

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

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

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

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

  9. 【C#复习总结】 Async 和 Await 的异步编程

    谈到异步,必然要说下阻塞,在知乎上看到了网友举的例子非常省动,在这里我引用下. 怎样理解阻塞非阻塞与同步异步的区别? 老张爱喝茶,废话不说,煮开水. 出场人物:老张,水壶两把(普通水壶,简称水壶:会响 ...

随机推荐

  1. sqlmap --tamper 绕过WAF脚本分类整理

    分类: https://blog.csdn.net/whatday/article/details/54774043 详细介绍: https://blog.csdn.net/qq_34444097/a ...

  2. IDF-简单题目writeup

    1. 被改错的密码 原题: 从前有一个熊孩子入侵了一个网站的[数据库],找到了管理员密码,手一抖在[数据库]中修改了一下,现在的密码变成了ca9cc444e64c8116a30la00559c042b ...

  3. linux服务器硬盘IO读写负载高来源定位 pt-ioprofile

    首先 .用top命令查看   1 2 3 4 5 top - 16:15:05 up 6 days,  6:25,  2 users,  load average: 1.45, 1.77, 2.14 ...

  4. nginx 499状态码

    Web服务器在用着nginx,在日志中偶尔会看到有499这个错误. rfc2616中,400-500间的错误码仅定义到了417,所以499应该是nginx自己定义的.后来想到读读nginx代码,疑问立 ...

  5. (golang)HTTP基本认证机制及使用gocolly登录爬取

    内网有个网页用了HTTP基本认证机制,想用gocolly爬取,不知道怎么登录,只好研究HTTP基本认证机制 参考这里:https://www.jb51.net/article/89070.htm 下面 ...

  6. 二 Struts2 接收数据

    struts2绑定页面参数三种方式1.普通属性:在action中写与页面参数相同的属性名,然后set方法2.用对象来接收:在action中写一个对象,表单元素名改为:对象名.属性名3.用实现Model ...

  7. opn要求

    1.在公司 ♦可以通过阿里云的公网ip访问pg 2.不在公司 ♦需要连接VPN才可访问阿里云的公网ip的应用(假定pg),但是特别的应用不在公司也可直接访问(假定gitlab) 思路提示:vpn黑白名 ...

  8. android 图片上传图片 报Socket: Broken pipe

    上传图片的时候报如下错误: 上传失败的原因是服务器限制了文件上传的大小.让服务端改一下配置文件就好了

  9. echarts中饼图显示百分比

    通过echarts制作饼图,需要通过鼠标移动到对应的扇形才能才看数值和百分比. 解决这个问题参考的是将鼠标移动到扇形上的显示方法:     tooltip : {         trigger: ' ...

  10. window.onload 与 $(document).ready() 的区别

    以浏览器装载文档为例,在页面加载完毕后,浏览器会通过 JavaScript 为 DOM 元素添加事件.在常规的 JavaScript 代码中,通常使用 window.onload 方法 ,而在 jQu ...