async,await执行流看不懂?看完这篇以后再也不会了

昨天有朋友在公众号发消息说看不懂await,async执行流,其实看不懂太正常了,因为你没经过社会的毒打,没吃过牢饭就不知道自由有多重要,没生过病就不知道健康有多重要,没用过ContinueWith就不知道await,async有多重要,下面我举两个案例佐证一下?

一:案例一 【嵌套下的异步】

写了这么多年的程序,相信大家都知道连接数据库少不了这几个对象,DbConnection,DbCommand,DbDataReader等等。。先来看看ContinueWith在连接数据库时嵌套过深的尴尬。

1. NetFramework 4.0之前的写法

这个时期的代码没有什么好说的,都是程式代码,一撸到底,简洁明了。

        public static int SyncGetCount(){using (var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;")){connection.Open();using (var command = connection.CreateCommand()){command.CommandText = "select count(1) from messages";var count = command.ExecuteScalar();Console.WriteLine($"记录条数:{count}");return Convert.ToInt32(count);}}}-------- output -------------记录条数:75896

2. NetFramework 4.0下ContinueWith的写法

当年异步和并发编程概念特别火,火热度参考现在的直播带货,这个时期的C#率先使用新的Task一网兜,在数据库操作的几大类中开始有了Async结尾的方法,如OpenAsync,ExecuteScalarAsync,ReadAsync 等等,但遗憾的是那时写异步,只能像下面这样写。

        public static Task<object> ContinueWithGetCount(){var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;");var task = connection.OpenAsync().ContinueWith(t1 =>{var command = connection.CreateCommand();command.CommandText = "select count(1) from messages";return command.ExecuteScalarAsync().ContinueWith(t2 =>{command.Dispose();connection.Dispose();Console.WriteLine($"记录条数:{t2.Result}");return t2.Result;});}).Unwrap();return task;}-------- output -------------记录条数:75896

相比同步代码,这异步代码写的是不是很憋屈,为了应对渐进式的Async方法,我不得不进行ContinueWith的深层嵌套,如果Async更多,那对可读性将是毁灭性的打击,这就是所谓的回调地狱。

3. NetFramework 4.5 下 await,async的写法

写到这里让我想起了邢老大的那本自传书《左手梦想,右手疗伤》,这苦这心酸只有真正经历过的人才会懂,没有人能够随随便便成功,接下来大家的期望就是如何做到有同步式的代码又有异步功效,鱼和熊掌我都要,当然是可以的,看看如何用await,async进行改造。

public static async Task<int> AsyncGetCount(){using (var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;")){await connection.OpenAsync();using (var command = connection.CreateCommand()){command.CommandText = "select count(1) from messages";var count = await command.ExecuteScalarAsync();Console.WriteLine($"记录条数:{count}");return Convert.ToInt32(count);}}}-------- output -------------记录条数:75896

上面这代码太简洁了,眼花的朋友还以为是同步代码呢?改造的地方也仅仅是方法签名处加上一个async,异步方法前加上await,相当于痛苦版的ContinueWith。

二:案例二 【循环下的异步】

上一个案例只是使用ExecuteScalarAsync从数据库中读取一个值来得到表中的记录数,在业务开发中更多的是使用ExecuteReader从数据库中获取批量记录,这个就涉及到了如何在循环中使用异步,想想就太苦难了(┬_┬)。

1. NetFramework 4.0之前的写法

这里我从messages表中读取5条记录,然后输出到控制台,详细代码如下:

public static List<string> SyncGetMessageList(){var messageList = new List<string>();using (var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;")){connection.Open();using (var command = connection.CreateCommand()){command.CommandText = "select message from messages limit 5;";using (var reader = command.ExecuteReader()){while (reader.Read()){messageList.Add(reader.GetString("message"));}}}}messageList.ForEach(Console.WriteLine);return messageList;}------------- output ----------------你需要忘记失去的,感激拥有的,和期待将至的。
以前的找不到了。
对于编译错误,删除Pods文件夹然后重新pod install已经成为经验。次。
Hello,Is there anyone here?
放松心情

2. NetFramework 4.0下ContinueWith的写法

要想用ContinueWith完成这功能,最简单有效的办法就是使用递归,用递归的方式把若干个ContinueWith串联起来,而要用递归的话还要单独定义一个方法,写的有点乱,大家将就着看吧。

    public class Program{public static void Main(string[] args){var task = ContinueWithAsyncGetMessageList();task.Result.ForEach(Console.WriteLine);Console.Read();}public static Task<List<string>> ContinueWithAsyncGetMessageList(){var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;");var task = connection.OpenAsync().ContinueWith(t1 =>{var messageList = new List<string>();var command = connection.CreateCommand();command.CommandText = "select message from messages limit 5;";return command.ExecuteReaderAsync().ContinueWith(t2 =>{var reader = (MySqlDataReader)t2.Result;return GetMessageList(reader, messageList).ContinueWith(t3 =>{reader.Dispose();command.Dispose();connection.Dispose();});}).Unwrap().ContinueWith(t3 => messageList);}).Unwrap();return task;}/// <summary>/// 采用递归处理循环/// </summary>/// <param name="reader"></param>/// <param name="messageList"></param>/// <returns></returns>public static Task<List<string>> GetMessageList(MySqlDataReader reader, List<string> messageList){var task = reader.ReadAsync().ContinueWith(t =>{if (t.Result){var massage = reader.GetString("message");messageList.Add(massage);return GetMessageList(reader, messageList);}else{return Task.FromResult(new List<string>());}}).Unwrap();return task;}}------------ output ----------------
你需要忘记失去的,感激拥有的,和期待将至的。
以前的找不到了。
对于编译错误,删除Pods文件夹然后重新pod install已经成为经验。次。
Hello,Is there anyone here?
放松心情

在递归下探的过程中把messageList集合给填满了,而后将messageList返回给调用端即可,如果没看明白,我画一张图吧!

3. NetFramework 4.5 下 await,async的写法

????,刚刚是不是噩梦般经历,救世主来啦,还是要鱼和熊掌一起兼得。

public static async Task<List<string>> AsyncGetMessageList(){var messageList = new List<string>();using (var connection = new MySqlConnection("server=xxx.xxx.xxx.xxx;userid=xxx;password=xxx;database=xxx;charset=utf8;port=3306;")){await connection.OpenAsync();using (var command = connection.CreateCommand()){command.CommandText = "select message from messages limit 5;";using (var reader = await command.ExecuteReaderAsync()){while (await reader.ReadAsync()){messageList.Add(reader["message"].ToString());}}}}return messageList;}------------ output ----------------
你需要忘记失去的,感激拥有的,和期待将至的。
以前的找不到了。
对于编译错误,删除Pods文件夹然后重新pod install已经成为经验。次。
Hello,Is there anyone here?
放松心情

天底下还有如此简洁的代码就可以实现ContinueWith那种垃圾般代码所实现的功能,我都想仰天长啸,我太难了。

三:总结

还是那句话,你没有被伤过,永远不会体会到那种刻骨铭心的痛。

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

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

相关文章

如何分析EFCore引发的内存泄漏

调查实体框架核心中的内存泄漏不要让内存泄漏成为洪水术语“内存泄漏”和“ .NET应用程序”不是经常一起使用。但是&#xff0c;我们最近在一个.NET Core Web应用程序中出现了一系列内存不足异常。事实证明&#xff0c;此问题是由Entity Framework Core中的行为更改引起的&…

数据结构与算法-- 二叉树中和为某一值的路径

二叉树中和为某一值的路径 题目&#xff1a;输入一颗二叉树和一个整数&#xff0c;打印出二叉树中节点值的和为给定值的所有路径。从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径。我们用二叉树节点的定义沿用之前文章中 二叉查找树实现原理定义。如下&#xff…

微服务统计,分析,图表,监控, 分布式追踪一体化的 HttpReports 在 .Net Core 的应用...

前言介绍HttpReports 是针对.Net Core 开发的轻量级APM系统&#xff0c;基于MIT开源协议, 使用HttpReports可以快速搭建.Net Core环境下统计,分析,图表,监控&#xff0c;分布式追踪一体化的站点&#xff0c; 适应.Net Core WebAPI,MVC&#xff0c;Web项目, 通过引用Nuget构建Da…

WPF 创建自定义面板

前面两个章节分别介绍了两个自定义控件:自定义的ColorPicker和FlipPanel控件。接下来介绍派生自定义面板以及构建自定义绘图控件。创建自定义面板是一种特殊但较常见的自定义控件开发子集。前面以及介绍过有关面板方面的知识&#xff0c;了解到面板驻留一个或多个子元素&#x…

vue.js中mock本地json数据

vue.js中mock本地json数据 新版本的vue项目中已经将dev-server.js&#xff0c;dev-client.js两个js文件合并到了webpack.dev.conf.js文件中&#xff0c;以下分别是新旧版本的build目录结构&#xff1a; 新版本&#xff1a; 旧版本&#xff1a; 本次验证mock&#xff1a;运…

互联网40岁失业是一个无法打破的魔咒吗?

最近刚刚过完生日&#xff0c;又大了一岁&#xff0c;距离40岁又进了一步。年纪大了&#xff0c;就要多复盘。最近几天思考的比较多&#xff0c;因为身边失业的朋友开始多了起来。我又有点陷入担忧、焦虑的心态了。好在我一直是个有阿Q精神的中年油腻男&#xff0c;很快安抚好自…

数据结构与算法--复杂链表的复制

复杂链表的复制 题目&#xff1a;实现一个函数complexListNode 复制一个复杂链表。在链表中&#xff0c;每个节点除了有一个next指针指向下一个节点&#xff0c;还有另外一个before节点&#xff0c;before节点指向链表中任意一个节点&#xff0c;或者null节点。链表节点定义使…

如何实时主动监控你的网站接口是否挂掉并及时报警

“ 阅读本文大概需要 10 分钟。 ”最近我在公司负责的业务已经正式投入上线了&#xff0c;既然是线上环境&#xff0c;那么就需要保证其可用性。我负责的业务其中就包括一个 Web Service&#xff0c;我需要保证 Service 的每个接口都是可用的&#xff0c;如果某个时间流量大了或…

数据结构与算法--二叉查找树转顺序排列双向链表

二叉查找树转顺序排列双向链表 题目&#xff1a;输入一颗二叉查找树&#xff0c;将二叉查找树转成一个排序的双向链表&#xff0c;要求不能创建任何新节点&#xff0c;只调整树节点中指针的指向。例如下图所示&#xff1a; 本次二叉查找树节点定义使用之前文章 数据结构与算法…

5种避免C#.NET中因事件造成内存泄漏的技术

原文来自互联网&#xff0c;由长沙DotNET技术社区编译。 5种避免C&#xff03;.NET中事件造成的内存泄漏的技术C&#xff03;&#xff08;通常是.NET&#xff09;中的事件注册是内存泄漏的最常见原因。至少从我的经验来看。实际上&#xff0c;我从事件中看到了太多的内存泄漏&a…

数据结构与算法--字符串的排列组合问题

字符串的全排列 题目&#xff1a;输入一个字符串&#xff0c;打印出改字符串中所有字符的所有排列。例如输入字符串abc&#xff0c;那么打印出由a&#xff0c;b&#xff0c;c字符组成的所有字符串&#xff1a;abc&#xff0c;acb&#xff0c;bac&#xff0c;bca&#xff0c;cab…

[GitHub] 75+的 C# 数据结构和算法实现

C#中标准数据结构和算法的即插即用类库项目GitHub&#xff1a;https://github.com/aalhour/C-Sharp-AlgorithmsWatch: 307 Star: 3.4k Fork: 910o---o | |/ --O---O--O | |\ --O---O--o---o | |O o o--o o--o o---o o-O-o …

我是如何一步步的在并行编程中将lock锁次数降到最低实现无锁编程

在并行编程中&#xff0c;经常会遇到多线程间操作共享集合的问题&#xff0c;很多时候大家都很难逃避这个问题做到一种无锁编程状态&#xff0c;你也知道一旦给共享集合套上lock之后&#xff0c;并发和伸缩能力往往会造成很大影响&#xff0c;这篇就来谈谈如何尽可能的减少lock…