zoukankan      html  css  js  c++  java
  • Task 异步小技巧

    原文地址:Task 异步小技巧 - 一事冇诚 - 博客园 (cnblogs.com)

    async Task 语法糖出来后,异步编程变得非常简单,适合需要耗费较长时间的任务。

    有些小伙伴使用后可能会非常疑惑,使用异步和同步,在耗时上几乎没有差别。

    下面我们看一个例子,场景是需要调用多个第三方的WebApi,分别是获取名称、年龄、性别,由于网络环境等原因,api响应时间可能会接近1秒

     1 public async Task Test()
     2 {
     3     var sw = new Stopwatch();
     4     sw.Start();
     5 
     6     var userName = await GetUserNameAsync();
     7     var userAge = await GetUserAgeAsync();
     8     var userSex = await GetUserSexAsync();
     9 
    10     sw.Stop();
    11     var ts = sw.Elapsed;
    12     Console.WriteLine($"总共耗时:{ts.TotalMilliseconds}ms");
    13 }
    14 
    15 private async Task<string> GetUserNameAsync()
    16 {
    17     await Task.Delay(500);
    18     return "小明";
    19 }
    20 
    21 private async Task<string> GetUserAgeAsync()
    22 {
    23     await Task.Delay(800);
    24     return "11";
    25 }
    26 
    27 private async Task<string> GetUserSexAsync()
    28 {
    29     await Task.Delay(900);
    30     return "11";
    31 }

    运行后发现,这个时间2秒多,这用户体验肯定是无法忍受的

     导致这样结果的原因是每次进行异步调用的时候,都在异步函数前加上了 await ,这会导致该线程阻塞,等待直到结果返回,每个异步函数都await,时间自然就叠加了,为了解决这个问题,使用一个小技巧,可以将代码改成下面这样

     1 public async Task Test()
     2 {
     3     var sw = new Stopwatch();
     4     sw.Start();
     5 
     6     var userNameTask =  GetUserNameAsync();
     7     var userAgeTask =  GetUserAgeAsync();
     8     var userSexTask =  GetUserSexAsync();
     9 
    10     var userName = await userNameTask;
    11     var userAge = await userAgeTask;
    12     var userSex = await userSexTask;
    13 
    14     sw.Stop();
    15     var ts = sw.Elapsed;
    16     Console.WriteLine($"总共耗时:{ts.TotalMilliseconds}ms");
    17 }
    18 
    19 private async Task<string> GetUserNameAsync()
    20 {
    21     await Task.Delay(500);
    22     return "小明";
    23 }
    24 
    25 private async Task<string> GetUserAgeAsync()
    26 {
    27     await Task.Delay(800);
    28     return "11";
    29 }
    30 
    31 private async Task<string> GetUserSexAsync()
    32 {
    33     await Task.Delay(900);
    34     return "11";
    35 }

    这次运行的总耗时,就是3个异步中,耗时最长那个 GetUserSexAsync

     为什么会这样呢,这个小技巧的关键是这里,当执行到异步函数的时候,不加 await,不进行等待,这样就不会造成阻塞,让这些任务乖乖在别的线程的执行,当需要用到他们的时候,再去等待返回值,所以时间上不会进行叠加,哪个最长,总耗时就是哪个

    1 var userNameTask =  GetUserNameAsync();
    2 var userAgeTask =  GetUserAgeAsync();
    3 var userSexTask =  GetUserSexAsync();
    4 
    5 var userName = await userNameTask;
    6 var userAge = await userAgeTask;
    7 var userSex = await userSexTask;

     有不对、不好的地方请大佬们指正,我会改正过来,感谢各位大佬

  • 相关阅读:
    浅谈SQL优化入门:1、SQL查询语句的执行顺序
    RabbitMQ 第三课 Exchange交换机详解
    RabbitMQ 第二课 快速入门
    RabbitMQ 第一课 RabbitMQ基本概念
    別人的JVM博客总结
    MySQL面试题 数据库MySQL经典面试题之SQL语句
    Swagger介绍及使用
    hcjk_SQL_FinReport_ismealFlag_Version
    hcjk_SQL 退费干掉,组套全展开,但0元被删掉了,退费的打印待沟通
    hcjk_fr 查询SQL,支持组套
  • 原文地址:https://www.cnblogs.com/ysmc/p/15409898.html
Copyright © 2011-2022 走看看