Fork me on GitHub

考虑用Task.WhenAll

  异步能在一定场景中带性能的飞跃,同步调用性能,也以带来时间的节省。

先看一下被调用的api:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebAPI.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
    {
        private readonly ILogger<HomeController> _logger;
        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }
        [HttpGet("/api001")]
        public async Task<IActionResult> GetAPI001()
        {
            _logger.LogInformation("GetAPI001");
            await Task.Delay(1000);
            return new JsonResult(new { result = true, data = "api001 返回成功" });
        }
        [HttpGet("/api002")]
        public async Task<IActionResult> GetAPI002()
        {
            _logger.LogInformation("GetAPI002");
            await Task.Delay(1000);
            if (DateTime.Now.Second % 2 == 0)
            {
                throw new Exception("api002异常");
            }
            return new JsonResult(new { result = true, data = "api002 返回成功" });
        }
        [HttpGet("/api003")]
        public async Task<IActionResult> GetAPI003()
        {
            _logger.LogInformation("GetAPI003");
            await Task.Delay(1000);
            return new JsonResult(new { result = true, data = "api003 返回成功" });
        }
    }
}

调用时反序列化的实体类

class ResponseResult<T>
    {
        public bool Result { get; set; }
        public string Message { get; set; }
        public T Data { get; set; }
    }

三个api的调用方法

private static async Task<string> GetAPI001(HttpClient httpClient)
{
    var content = await httpClient.GetStringAsync("http://localhost:5000/api001");
    var result = JsonSerializer.Deserialize<ResponseResult<string>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    if (result.Result)
    {
        return result.Data;
    }
    else
    {
        return result.Message;
    }
}
private static async Task<string> GetAPI002(HttpClient httpClient)
{
    var content = await httpClient.GetStringAsync("http://localhost:5000/api002");
    var result = JsonSerializer.Deserialize<ResponseResult<string>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    if (result.Result)
    {
        return result.Data;
    }
    else
    {
        return result.Message;
    }
}
private static async Task<string> GetAPI003(HttpClient httpClient)
{
    var content = await httpClient.GetStringAsync("http://localhost:5000/api003");
    var result = JsonSerializer.Deserialize<ResponseResult<string>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    if (result.Result)
    {
        return result.Data;
    }
    else
    {
        return result.Message;
    }
}

同步的调用方式

static async Task SyncCall()
{
    using var httpClient = new HttpClient();
    try
    {
        var result1 = await GetAPI001(httpClient);
        WriteLine(result1);
    }
    catch (Exception exc)
    {
        WriteLine(exc.Message);
    }
    try
    {
        var result2 = await GetAPI002(httpClient);
        Console.WriteLine(result2);

    }
    catch (Exception exc)
    {
        WriteLine(exc.Message);
    }
    try
    {
        var result3 = await GetAPI003(httpClient);
        Console.WriteLine(result3);
    }
    catch (Exception exc)
    {
        WriteLine(exc.Message);
    }
}

调用方式

static async Task Main(string[] args)
{
    while (true)
    {
        WriteLine("回车开始执行");
        ReadLine();
        var stopwatch = Stopwatch.StartNew();
        await SyncCall();
        WriteLine($"用时{stopwatch.ElapsedMilliseconds}ms");
    }
}

同步的调用,运行三次调用是三次的时间,3202ms,如果有异常不干扰其他api调用。

 

 

 

static async Task AsyncCall()
{
    using var httpClient = new HttpClient();
    var allTasks = Task.WhenAll(GetAPI001(httpClient), GetAPI002(httpClient), GetAPI003(httpClient));
    try
    {
        var results = await allTasks;
        foreach (var result in results)
        {
            Console.WriteLine(result);
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine($"捕捉到的异常:{exc.Message}");
    }
    if (allTasks.Exception != null)
    {
        Console.WriteLine($"AllTasks异常:{ allTasks.Exception.Message}");
    }
}

同步调用成功时间是1156ms,时间缩短了,但三个api调用,如果有异常,则全军覆没。

 

 

 先择适合的方式,打造更优的应用。

 

  想要更快更方便的了解相关知识,可以关注微信公众号 
 

 

 

posted @ 2022-02-11 15:30  桂素伟  阅读(74)  评论(0编辑  收藏  举报