最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

当前播报:对于async和await的使用方式、作用效果不怎么理解 ?没关系,初步看这篇就够了。

来源:博客园

结论

同步还是异步,区别如下:


(资料图片仅供参考)

  • 同步:你使用await修饰符去调用一个异步(async)方法(是异步方法,不过是阻塞式的,可简单理解为同步);
  • 异步:你获取异步方法返回的Task,就是异步(后文有代码示例);
  • 可以实现多任务执行顺序执行且不阻塞。

概述

async(C# 参考)

async是“异步”的简写,使用async修饰符可将方法、lambda 表达式或匿名方法指定为异步。

如果对方法或表达式使用此修饰符,则其称为异步方法 。

如下示例定义了一个名为ExampleMethodAsync的异步方法:

public async Task ExampleMethodAsync(){    //...}

await(C# 参考)

await运算符暂停对其所属的async方法的求值,直到其操作数表示的异步操作完成。

异步操作完成后,await运算符将返回操作的结果(如果有)。

await运算符应用到表示已完成操作的操作数时,它将立即返回操作的结果,而不会暂停其所属的方法。

await运算符不会阻止计算异步方法的线程。

await运算符暂停其所属的异步方法时,控件将返回到方法的调用方。

官网说的话是不是听不明白?没关系,你就理解为添加了await修饰符后,必须要等调用返回后才能继续执行下一步。

如下示例:

public async Task ExampleMethodAsync(){    //...    //这添加了await,执行到这里需要等待MethodAwiat方法执行完成后才会往下继续执行。    int result = await MethodAwiat();    //...}public async Task MethodAwiat(){    //...}

作用及基本用法

await和async可以简化我们异步编程,也可以让我们以一种类似同步编程的方式来进行异步编程。

另外当我们需要不阻塞主线程异步执行,但又要有顺序的执行相关代码的时候,await/async就可以排上用场。

基本用法如下示例:

///         /// 可异步可同步        ///         ///         public  async Task TestAsync()        {            Thread.Sleep(3000);            Task task = new Task(() =>            {                return "主程序返回后我还在执行数据:我是复杂的异步执行的方法,不阻碍主程序执行。。。。。";            });            task.Start();            return await task;        }        // await 使得任务同步        public  async void T1()        {            // 使用 await 关键字,代表等待执行完成,同步            string time = await TestAsync();            Console.WriteLine(time);            Console.WriteLine("执行完毕");        }        // 直接获得返回的 Task,实现异步        public  void T2()        {            // 获取 Task 任务对象,后面的逻辑过程可以弄成异步            Task task = TestAsync();            // 这里可以处理其它事情,处理完毕后,再获取执行结果            Console.WriteLine("执行完毕");            Console.WriteLine(task.Result);        } 

实现多任务顺序执行且不阻塞

以微软文档的做早餐的案例加以简化来讲解 【使用Async和Await可以实现多任务顺序执行且不阻塞】。

主线任务任务:倒橙汁 -> 烤面包->煎培根->煎鸡蛋->倒咖啡。

1.同步执行

我们任务逐步顺序执行如下,耗时:17064毫秒(17.064秒):

using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;using System;using System.Diagnostics;using System.Threading;namespace ConsoleApp1{    class Program    {        static void Main(string[] args)        {            Stopwatch stopwatch = new Stopwatch();            stopwatch.Start();            PourOJ();            PourCoffee();            ToastBread();            FryBacon();            FryEggs();            Console.WriteLine("早餐已经做完!");            stopwatch.Stop();            Console.WriteLine($"做早餐总计耗时:{stopwatch.ElapsedMilliseconds}");            Console.ReadLine();        }        //倒橙汁        private static void PourOJ()        {            Thread.Sleep(1000);            Console.WriteLine("倒一杯橙汁");        }        //烤面包        private static void ToastBread()        {            Console.WriteLine("开始烤面包");            Thread.Sleep(3000);            Console.WriteLine("烤面包好了");        }        //煎培根        private static void FryBacon()        {            Console.WriteLine("开始煎培根");            Thread.Sleep(6000);            Console.WriteLine("培根煎好了");        }        //煎鸡蛋        private static void FryEggs()        {            Console.WriteLine("开始煎鸡蛋");            Thread.Sleep(6000);            Console.WriteLine("鸡蛋好了");        }        //倒咖啡        private static void PourCoffee()        {            Thread.Sleep(1000);            Console.WriteLine("倒咖啡");        }    }}

2.并行执行

如果此时我们每一项任务都有一个单独的人去完成,将会缩短时间将近3倍(当然不能单纯的用时间量化他),

如下,耗时6041毫秒(6.041秒):

using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;using System;using System.Collections.Generic;using System.Diagnostics;using System.Threading;using System.Threading.Tasks;namespace ConsoleApp1{    class Program    {        static void Main(string[] args)        {            Test();            Console.ReadLine();        }        private static void Test()        {            Stopwatch stopwatch = new Stopwatch();            stopwatch.Start();            List tasks = new List() { PourOJ(), ToastBread(), FryBacon(), FryEggs(), PourCoffee() };            Task.WhenAll(tasks).ContinueWith((t) =>            {                Console.WriteLine("早餐已经做完!");                stopwatch.Stop();                Console.WriteLine($"做早餐总计耗时:{stopwatch.ElapsedMilliseconds}");            });        }        //倒橙汁        private static async Task PourOJ()        {            await Task.Delay(1000);            Console.WriteLine("倒一杯橙汁");        }        //烤面包        private static async Task ToastBread()        {            Console.WriteLine("开始烤面包");            await Task.Delay(3000);            Console.WriteLine("烤面包好了");        }        //煎培根        private static async Task FryBacon()        {            Console.WriteLine("开始煎培根");            await Task.Delay(6000);            Console.WriteLine("培根煎好了");        }        //煎鸡蛋        private static async Task FryEggs()        {            Console.WriteLine("开始煎鸡蛋");            await Task.Delay(6000);            Console.WriteLine("鸡蛋好了");        }        //倒咖啡        private static async Task PourCoffee()        {            await Task.Delay(1000);            Console.WriteLine("倒咖啡");        }    }}

3.并行且可指定顺序执行

但是我们不可能每次做早餐都有那么多人同时做,

需求变更:如果现在要求,先倒橙汁,然后倒咖啡,其余的操作并行执行,应该如何操作呢?

只需将以上案例的主线程Test 方法修改如下,其他的不变,耗时8073毫秒(8.073秒):

private static async void Test()        {            Stopwatch stopwatch = new Stopwatch();            stopwatch.Start();            await PourOJ();             //倒橙汁            await PourCoffee();         //然后倒咖啡            List tasks = new List() { ToastBread(), FryBacon(), FryEggs() };//子任务List            await Task.WhenAll(tasks);  //其余的并行操作            Console.WriteLine("早餐已经做完!");            stopwatch.Stop();            Console.WriteLine($"做早餐总计耗时:{stopwatch.ElapsedMilliseconds}");        }

总结

我们发现,用好了async和await确实很节省时间。

大家可以想想怎么优雅的在异步里面开多线程(多主线程多子线程)最节省时间。

参考文献

  • 使用 Async 和 Await 的异步编程(C# )

  • async(C# 参考)

  • await(C# 参考)

喜欢就点赞加关注。

欢迎关注订阅微信公众号【熊泽有话说】,更多好玩易学知识等你来取作者:熊泽-学习中的苦与乐公众号:熊泽有话说QQ群:711838388出处:https://www.cnblogs.com/xiongze520/p/16976348.html您可以随意转载、摘录,但请在文章内注明作者和原文链接。

关键词: 异步方法 执行完毕 异步操作