考虑用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调用,如果有异常,则全军覆没。
先择适合的方式,打造更优的应用。
想要更快更方便的了解相关知识,可以关注微信公众号
****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524