C#基于任务的异步编程基础(三)之异步方法并行

在上篇《基于任务的异步编程基础(二)之async和await创建异步方法》介绍了async和await的基本用法,这节将重点介绍如何并行执行异步和多个异步方法的异常处理。

一个异步方法中,可以调用一个或多个异步方法,代码如何实现主要取决于一个异步方法的结果是否依赖另外一个异步方法,本文只展示多个异步方法独立运行的场景,一般情况下一个异步方法不会依赖另一个异步方法,否则还不如同步执行更易阅读。

一、命名规范

基于任务的异步模式指定,在异步方法名后加上Async后缀,即XXXAsync格式,虽然在方法定义时可能已经使用async关键字标识方法是异步方法,但是在命名方法时还是需要遵循命名格式,即使不遵循并不会影响程序运行,以便增强代码阅读性。

二、按顺序调用异步方法

创建如下代码:

        static void Main(string[] args)
        {
           Console.WriteLine($" Start Time:{DateTime.Now.ToString()}");
           MultipleAsyncMethods();
           Console.ReadKey();
        }
        private static string PrintName(string name)
        {
            Thread.Sleep(2000);
            return string.Format($"{DateTime.Now.ToString()} I am {name}");
        }
        private static Task<string> PrintNameAsync(string name)
        {
            return Task.Run(() =>
            {
                return PrintName(name);
            });
        }
        private async static void MultipleAsyncMethods()
        {
            string str1 = await PrintNameAsync("joe");
            string str2 = await PrintNameAsync("marry");
            string str3 = PrintName("doge");
            Console.WriteLine($" Result Time:{DateTime.Now.ToString()}\n str1:{str1}\n str2:{str2}\n str3:{str3}");
        }

运行结果如图:

从如上运行结果至少可以说明两个问题:

1、使用await关键字调用异步方法,在MultipleAsyncMethods的方法内调用的时间依旧和同步执行耗时一样,即使是不同线程

2、使用await关键字时,方法内其他代码不会被执行,即使调用了同步方法,当然调用MultipleAsyncMethods的线程不会阻塞会继续执行其他代码(本例没有展示相关代码,可以详见上篇《基于任务的异步编程基础(二)之async和await创建异步方法》)。

三、使用组合器提升执行效率

从上面使用await同步执行异步方法看,即使是异步执行,耗时却和同步相同,使用异步的目的之一便是提升程序响应效率,减少客户端等待,所以上面的代码并没有减少客户端等待还需优化。假如异步方法不依赖其他异步方法,那么就可以不使用await,而是把每个异步方法的返回值结果赋值给Task变量。由此将MultipleAsyncMethods更改成如下代码:

 private async static void MultipleAsyncMethods()
        {
            Task<string> str1 =  PrintNameAsync("joe");
            Task<string> str2 =  PrintNameAsync("marry");
            string str3 = PrintName("doge");
            await Task.WhenAll(str1,str2);
            string str4 = PrintName("hame");
            Console.WriteLine($" Result Time:{DateTime.Now.ToString()}\n str1:{str1.Result}\n str2:{str2.Result}\n str3:{str3}\n str4:{str4}");
        }

运行结果如下:

从上图运行结果可以得出以下结论:

1、使用WhenAll组合器同样达到等待所有结果返回的目的,但是await之前的代码是并行运行的,大大的减少了程序运行时间

2、await能阻塞方法运行,使用不当不仅达不到异步编程的目的,反而增加代码的阅读难度和资源开销。

3、在多个异步方法执行甚至包含同步方法调用的时候,需要充分考虑实际项目的业务逻辑,尽量同步执行和异步执行分开,仔细设计异步方法,异步方法通常都是比较耗时方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值