惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 最新话题
小众软件
小众软件
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Visual Studio Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
T
Tailwind CSS Blog
Recorded Future
Recorded Future
雷峰网
雷峰网
WordPress大学
WordPress大学
A
Arctic Wolf
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Project Zero
Project Zero
T
Tor Project blog
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Spread Privacy
Spread Privacy
G
Google Developers Blog
Security Latest
Security Latest
MongoDB | Blog
MongoDB | Blog
T
Threatpost
I
InfoQ
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
S
Security Affairs
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
C
Cisco Blogs
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
aimingoo的专栏
aimingoo的专栏
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Google DeepMind News
Google DeepMind News
The Hacker News
The Hacker News
D
Docker
博客园 - 【当耐特】
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
PCI Perspectives
PCI Perspectives
Microsoft Azure Blog
Microsoft Azure Blog
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
Cloudbric
Cloudbric
A
About on SuperTechFans
F
Fortinet All Blogs

博客园 - 幸福的菜菜

windows下使用ACME申请SSL证书的办法 ElementPlus Radio 实现双击取消选择的效果 Windows10 LTSC版本 无法访问网络中部分的共享文件夹 SqlSugar : date绑定到XX失败,可以试着换一个类型,或者使用ORM自定义类型实现 VisualStudio Debug模式突然变慢 Visual Stadio 编译提示 The BaseOutputPath/OutputPath property is not set for project ... winform绘图与前端canvas绘图效率对比 node-sass编译不通过, 提示 “checking for Python executable "python2" in the PATH” winform 实现对usb热拔插的监听 Laravel The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths Wampserver 配置端口可访问服务 git credential for windows 总是弹出的问题 如何用B表的数据,更新A表的值 WampServer部署https 服务的过程 PHP 命名空间冲突解决方式 Windows下 Docker 简单部署 Django应用 C#实现后台格式化U盘的功能 Winform 实现断点续传的思路及代码 WAMPServer ServerName has syntax error 的问题(阿里云服务器上)
c# async await的使用方式及为啥要用它
幸福的菜菜 · 2022-01-21 · via 博客园 - 幸福的菜菜

c# 5的语法(.net framework 4.5+ 版本)引入了 async await的概念,再加上前端开发也经常出现这个概念。用的少,理解也不深,看到了一篇很容易入门的文章,所以在此写一些自己的理解:

本文来源于知乎的一篇文章,但是添加了一些自己的测试代码。知乎文章的链接如下

https://zhuanlan.zhihu.com/p/138805565

先来看一下顺序执行的例子

        internal static void Test()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Task task = new Task(CallMethod);
            //Task task = new Task(CallMethodAsync);
            task.Start();
            task.Wait();


            sw.Stop();
            Console.WriteLine("程序运行共 耗时:" + sw.ElapsedMilliseconds);
            Console.ReadLine();
        }

        static async void CallMethod()
        {
            Console.WriteLine(" Other Work 1111");
            string filePath = "d:\\sampleFile.txt";
            int a = ReadFile(filePath);

            Console.WriteLine(" Other Work 1");
            Thread.Sleep(1000);
            Console.WriteLine(" Other Work 2");
            Thread.Sleep(1000);
            Console.WriteLine(" Other Work 3");

            int length = a;
            Console.WriteLine(" Total length: " + length);

            Console.WriteLine(" After work 1");
            Console.WriteLine(" After work 2");
        }


        static int ReadFile(string file)
        {
            int length = 0;

            Console.WriteLine(" File reading is stating");
            using (StreamReader reader = new StreamReader(file))
            {
                // Reads all characters from the current position to the end of the stream asynchronously   
                // and returns them as one string.   
                string s = reader.ReadToEnd();

                length = s.Length;
            }
            Thread.Sleep(2000);
            //Console.WriteLine("Hello world");
            Console.WriteLine(" File reading is completed");
            return length;
        }

程序执行以后,输出如下:

 

可以看到,因为我在ReadFile 里面进行了延时,所以ReadFile内的函数耗时 + 函数外的耗时  = 4秒 左右

再看一下使用async await异步执行的例子

        internal static void Test()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            //Task task = new Task(CallMethod);
            Task task = new Task(CallMethodAsync);
            task.Start();
            task.Wait();


            sw.Stop();
            Console.WriteLine("程序运行共 耗时:" + sw.ElapsedMilliseconds);
            Console.ReadLine();
        }

        static async void CallMethodAsync()
        {
            Console.WriteLine(" Other Work 1111");
            string filePath = "d:\\sampleFile.txt";
            Task<int> task = ReadFileAsync(filePath);

            Console.WriteLine(" Other Work 1");
            Thread.Sleep(1000);
            Console.WriteLine(" Other Work 2");
            Thread.Sleep(1000);
            Console.WriteLine(" Other Work 3");

            int length = await task;
            Console.WriteLine(" Total length: " + length);

            Console.WriteLine(" After work 1");
            Console.WriteLine(" After work 2");
        }


        static async Task<int> ReadFileAsync(string file)
        {
            int length = 0;

            Console.WriteLine(" File reading is stating");
            using (StreamReader reader = new StreamReader(file))
            {
                // Reads all characters from the current position to the end of the stream asynchronously   
                // and returns them as one string.   
                string s = await reader.ReadToEndAsync();

                length = s.Length;
            }
            Thread.Sleep(2000);
            Console.WriteLine(" File reading is completed");
            return length;
        }

程序输出的结果如下:

 可以看到,使用 async await 的异步执行,只花费了2秒左右的时间。

这是为什么呢? 因为使用异步执行时,函数内部已经开启独立的Task 去执行了。所以函数主体依然能够一直运行,直至

这一步的时候,因为内外层都是2秒左右的延时,所以无需等待时间,极大地缩短了运行时间。

如果我们把 ReadFileAsync 的Sleep时间修改成三秒会发现输出更有意思了

 咦? 这里2秒,程序都跑完了,怎么才输出 Total length 以及结束的内容呢?这里就是异步编程的强大之处

如果使用传统的编程,那么这里 2 + 3 =5  秒程序才会结束

而如果使用异步编辑, 2< 3  = 3 秒程序实际就可以结束

这样子相比传统顺序执行的编程,那岂不是会有一个问题?函数主体都已经返回了,我却拿不到返回值,这咋整?

其实在ReadFile里面已经提供了范例: 如果要等  CallMethodAsync 的所有异步都结束再退出,可以将CallMethodAsync 改为 ReadFileAsync 的形式,在外层调用

修改之后得到的输出为:

如果不使用以上的方式,使用传统的编程方式,如何才能缩短执行时间呢?目前我是没想到更好,更优雅的方式……