异步能在一定场景中带性能的飞跃,同步调用性能,也以带来时间的节省。
先看一下被调用的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调用,如果有异常,则全军覆没。
先择适合的方式,打造更优的应用。