第十节:利用async和await简化异步编程模式的几种写法

一. 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(3000);
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(3000);
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 void3         /// 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(3000);
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 = 0;
10 //启动新线程完成任务
11 Task task = Task.Run(() =>
12 {
13 for (long i = 0; i < 100; 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 = 0;
11             //启动新线程完成任务
12             TaskFactory taskFactory = new TaskFactory();
13             Task<long> task = taskFactory.StartNew<long>(() =>
14             {
15                 for (long i = 0; i < 100; i++)
16                 {
17                     result += i;
18                 }
19                 return 1;
20             });
21             Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
22             Console.WriteLine("result:{0}", result);
23             return task;
24         }

 

代码结果:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十一节:深究用户模式锁的使用场景(异变结构、互锁、旋转锁)

一. 锁机制的背景介绍 本章节&#xff0c;将结合多线程来介绍锁机制&#xff0c; 那么问题来了&#xff0c;什么是锁呢&#xff1f; 为什么需要锁&#xff1f; 为什么要结合多线程来介绍锁呢&#xff1f;锁的使用场景又是什么呢&#xff1f; DotNet中又有哪些锁呢&#xff1f; …

第十三节:实际开发中使用最多的监视锁Monitor、lock语法糖的扩展、混合锁的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)

一. 监视锁(Monitor和lock) 1. Monitor类&#xff0c;限定线程个数的一把锁&#xff08;Synchronized lock是他的语法糖&#xff09;&#xff0c;两个核心方法&#xff1a; Enter&#xff1a;锁住某个资源。 Exit&#xff1a;退出某一个资源。 测试案例&#xff1a;开启5个线…

第十四节: 介绍四大并发集合类并结合单例模式下的队列来说明线程安全和非安全的场景及补充性能调优问题。

一. 四大并发集合类 背景&#xff1a;我们目前使用的所有集合都是线程不安全的 。 A. ConcurrentBag&#xff1a;就是利用线程槽来分摊Bag中的所有数据&#xff0c;链表的头插法,0代表移除最后一个插入的值. (等价于同步中的List) B. ConcurrentStack&#xff1a;线程安全的St…

第十五节:深入理解async和await的作用及各种适用场景和用法

一. 同步VS异步 1. 同步 VS 异步 VS 多线程 同步方法&#xff1a;调用时需要等待返回结果&#xff0c;才可以继续往下执行业务 异步方法&#xff1a;调用时无须等待返回结果&#xff0c;可以继续往下执行业务 开启新线程&#xff1a;在主线程之外开启一个新的线程去执行业…

@PostConstruct注解

PostConstruct是Java自己的注解. PostConstruct该注解被用来修饰一个非静态的void()方法. PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次. PostConstruct在构造函数之后执行,init()方法之前执行. 执行顺序 Constructor >> Autow…

springCloud五大组件--Gateway

SpringCloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 Spring Cloud Gateway 的目标&#…

多线程篇(被替换)

一. 背景 在刚接触开发的头几年里&#xff0c;说实话&#xff0c;根本不考虑多线程的这个问题&#xff0c;貌似那时候脑子里也有没有多线程的这个概念&#xff0c;所有的业务都是一个线程来处理&#xff0c;不考虑性能问题&#xff0c;当然也没有考虑多线程操作一条记录存在的并…

springCloud五大组件--Eureka

Spring Cloud 支持了 Zookeeper、Consul 和 Eureka&#xff0c;官方推荐 Eureka。 C(一致性)A(高可用)P(分区容错)理论&#xff0c;Eureka的选择就是放弃C&#xff0c;选择AP。 Eureka 采用纯 Java 实现&#xff0c;除实现了注册中心基本的服务注册和发现之外&#xff0c;极大…

.NET异步程序设计之任务并行库

目录 1.简介2.Parallel类 2.0 Parallel类简介2.1 Parallel.For()2.2 Parallel.ForEach()2.3 Parallel.Invoke()2.4 补充&#xff1a;线程安全集合3.Task类 3.0 Task类简介3.1 创建无返回值的Task任务3.2 创建有返回值的Task任务3.3 为Task添加延续任务3.4 Task.Delay3.5 Task对…

Mysql主从延时解决办法

1.忍受大法 第一种解决办法&#xff0c;很简单&#xff0c;无他&#xff0c;不管他&#xff0c;没有读到也没事。这时业务不需要任何改造&#xff0c;你好&#xff0c;我好&#xff0c;她也好~ 如果业务对于数据一致性要求不高&#xff0c;我们就可以采用这种方案。 2.数据同…

关于C#程序的单元测试

目录 1.单元测试概念2.单元测试的原则3.单元测试简单示例4.单元测试框架特性标签5.单元测试中的断言Assert6.单元测试中验证预期的异常7.单元测试中针对状态的间接测试8.单元测试在MVC模式中的实现8.单元测试相关参考9.示例源代码下载 志铭-2020年1月23日 11:49:41 1.单元测试…

NuGet是什么?理解与使用(上)

如果你了解python&#xff0c;那么它类似pip。 如果你了解nodejs&#xff0c;那么它类似npm。 如果你了解ruby&#xff0c;那么它类似gem。 对&#xff0c;它就是一个包&#xff08;package&#xff09;管理平台&#xff0c;确切的说是 .net平台的包管理工具&#xff0c;它提…

NuGet是什么?理解与使用(下)

本篇将回答下面几个问题&#xff1a; 如何解读NuGet Gallery上的包信息&#xff1f;如何上传NuGet包到NuGet Gallery&#xff1f;如何安装本地NuGet包&#xff1f;NuGet包的内容文件与目录结构&#xff1f; 如果你没看过上篇那么它在这里&#xff1a; 6号咸鱼&#xff1a;NuG…

C#多线程之旅(1)——介绍和基本概念

阅读目录 一、多线程介绍二、Join 和Sleep三、线程怎样工作四、线程和进程五、线程的使用和误用一、多线程介绍 C#通过多线程支持并行执行的代码。一个线程是一个独立执行的路径&#xff0c;可以同时与其他线程一起运行。一个C#客户端程序(Console,WPF,Winows Forms)开始于一个…

C#多线程之旅(2)——详解线程的开始和创建

阅读目录 代码下载一、线程的创建和开始二、传递数据给一个线程三、命名线程四、前台线程和后台线程五、线程优先级六、异常处理代码下载 Thread_博客园_cnblogs_jackson0714.zip 第一篇~第三篇的代码示例&#xff1a; 源码地址&#xff1a;https://github.com/Jackson0714/T…

C#多线程之旅(3)——线程池

阅读目录 代码下载一、介绍二、通过TPL进入线程池三、不用TPL进入到线程池v博客前言 先交代下背景&#xff0c;写《C#多线程之旅》这个系列文章主要是因为以下几个原因&#xff1a;1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的&#xff0c;如果没有…

C#多线程之旅(4)——APM初探

阅读目录 一、简单的串行执行程序 二、使用委托来实现APM源码地址&#xff1a;https://github.com/Jackson0714/Threads C#多线程之旅(4)——APM初探 v博客前言 先交代下背景&#xff0c;前面几张内容主要是介绍多线程的基本知识&#xff0c;这一章是因为正好接触到了APM&…

C#多线程编程系列(五)- C# ConcurrentBag的实现原理

目录 一、前言二、ConcurrentBag类三、 ConcurrentBag线程安全实现原理 1. ConcurrentBag的私有字段2. 用于数据存储的ThreadLocalList类3. ConcurrentBag实现新增元素4. ConcurrentBag 如何实现迭代器模式四、总结笔者水平有限&#xff0c;如果错误欢迎各位批评指正&#xff…

C#多线程编程系列(五)- 浅析C# Dictionary实现原理

目录 一、前言二、理论知识 1、Hash算法2、Hash桶算法3、解决冲突算法三、Dictionary实现 1. Entry结构体2. 其它关键私有变量3. Dictionary - Add操作4. Dictionary - Find操作5. Dictionary - Remove操作6. Dictionary - Resize操作(扩容)7. Dictionary - 再谈Add操作8. Col…

ASP.NET MVC 入门5、View与ViewData

本系列文章基于ASP.NET MVC Preview5. view在MVC模式中与用户进行最直接的接触&#xff0c;它负责数据的呈现。这里要注意一点就是&#xff0c;view只是负责数据的呈现&#xff0c;所以我们应该要尽量让view中不涉及业务逻辑的处理。 我们来添加一个Blog首页的view。在安装了…