6

Task 异步小技巧

 3 years ago
source link: https://www.cnblogs.com/ysmc/p/15409898.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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;

Recommend

  • 122
    • donthitsave.com 7 years ago
    • Cache

    Don't Hit Save - Completed Task

    October 17, 2017 - News Post Sigh... my hair looks stupid. This weekend, I received yet another lopsided pompadour haircut. It’s truly starting to feel like a Nashville thing. What is it with this town?

  • 71
    • gorealize.io 7 years ago
    • Cache

    Realize - Golang Task Runner

    Realize - Golang Task Runner

  • 64
    • Github github.com 7 years ago
    • Cache

    Release v2.0.0 · go-task/task · GitHub

    GitHub is where people build software. More than 28 million people use GitHub to discover, fork, and contribute to over 80 million projects.

  • 70
    • www.tuicool.com 7 years ago
    • Cache

    A universal task runner to run them all

    Today we’ll talk about a miscomfort that has been echoing in my head since a while ago: Task runners fatigue . We’ve come accross Grunt, Gradle, Gulp, NPM scripts, then rediscovered makefiles,...

  • 66
    • www.tuicool.com 6 years ago
    • Cache

    Julia parallel task runtime (WIP)

    This replaces the existing fork-join threading infrastructure with a parallel task runtime (partr) that implements parallel depth firs...

  • 78
    • www.tuicool.com 6 years ago
    • Cache

    Building a Better Task Sequence

    I’ve had this post in the queue for a while now and have been working on a script to help with some of this, but with the release of System Center Configuration Manager 1810 I don’t have to hack something together anymor...

  • 10

    渡劫 C++ 协程(4):通用异步任务 Task 发表于 2022-03-19 更新于 2022-03-20 阅读次数: 2 本文字数: 11k 阅读时长 ≈ 19 分钟协程主要用来降低异步任务的编写复杂度,异步任务各式各样,但归根结底就是一个结果的获取。

  • 8
    • blog.51cto.com 2 years ago
    • Cache

    Swoole 的异步 Task 任务详解

    Swoole 的异步 Task 任务详解 精选 原创 本文将从下面两方面讲述 Swoole Task...

  • 7

    在 Android 应用开发中,异步编程是不可避免的,而 Kotlin Flow 是一个强大的库,能够使异步操作更加优雅和易于管理。本文将深入探讨 Kotlin Flow 的使用方法,同时也会解析其背后的实现原理,帮助你更好地理解这一技术。 什么是...

  • 4

    本文同步自「我的 Memos - 随笔」,你也可访问 x.singee.me 查看我的全部碎碎念 在 Swift 上,执行一个异步的函数大体上有两种办法 DispatchQueue

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK