闽公网安备 35020302035485号
private async Task<TResult> DoSomeStuffAsync(..)
{
..
await ..
..
}
l 关键词 async 本身不具备什么意义,只是装饰,当方法冠以 async 关键词,方法体内允许使用 await|
|
非阻止操作 |
阻止操作 |
备注 |
| 获取任务返回 | await task | task.Wait / task.Result |
非阻塞:线程遇到 await 时会返回上一层调用者继续执行,如果没有上一级调用者,则释放该线程; 阻塞:线程在等待期间不能执行其他任务,也不释放线程,硬等
|
|
任一任务完成 |
await Task.WhenAny |
Task.WaitAny |
|
|
所有任务完成 |
await Task.WhenAll |
Task.WaitAll |
|
|
等待一段时间 |
await Task.Delay |
Thread.Sleep |
l 异步方法返回的值总是 Task 的实例,可以是 Task 类型或 Task<TResult>,其中 TResult 是执行的方法的返回类型
public static async Task Main(string[] args)
{
logMessage("Main <<----");
var task = GetUrlContentLengthAsync();
logMessage("Main ---->>");
await task;
logMessage("ALL COMPLETED");
}
static async Task<int> GetUrlContentLengthAsync()
{
logMessage("GetUrlContentLengthAsync start ");
using var client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("https://learn.microsoft.com/dotnet");
// Do some independent work..
// 堆代码 duidaima.com
var contents = await getStringTask;
logMessage("GetUrlContentLengthAsync end ");
return contents.Length;
}
static void logMessage(string msg)
{
Console.WriteLine($"{DateTime.Now.ToString("MM-dd HH:mm:ss.fff")} [{Thread.CurrentThread.ManagedThreadId}] {msg}");
}
打印结果:11-18 18:34:34.563 [1] Main <<---- 11-18 18:34:34.632 [1] GetUrlContentLengthAsync start 11-18 18:34:34.810 [1] Main ---->> 11-18 18:34:37.283 [7] GetUrlContentLengthAsync end 11-18 18:34:37.286 [7] ALL COMPLETED先分析一下 GetUrlContentLengthAsync 这个异步方法,简单归纳会存在以下步骤:

public static async Task Main(string[] args)
{
logMessage("Main <<----");
// fault example: if do not wait the result then we will do not know what happened on it
GetSomeStuff();
logMessage("Main ---->>");
}
这个异步任务已经在执行,但是却没有后续处理,不知道是成功或是失败,又或者一直在执行没有办法停止,这是危险的。 public async Task<ResultResponse> ValidateReceiptAsync(List<Guid> customerIds, ReceiptRequest request, CancellationToken cancellationToken)
{
var tokenTask = _medicalCheckServiceHelper.GetServiceToken(cancellationToken);
var medicalProvidersTask = _medicalProviderRepo.GetMedicalProvidersNames();
var customersTask = _customerService.GetByIdsAsync(customerIds);
var checkResults = await Task.WhenAll(request.UuidList.Select(uuid => _medicalCheckServiceHelper.GetResultAsync(uuid, tokenTask.Result, cancellationToken)));
return await ConsolidateReceiptsResult(medicalProvidersTask.Result, checkResults, await customersTask);
}
思考一下public async Task<ResultResponse> ValidateReceiptAsync(List<string> customerIds, ReceiptRequest request, CancellationToken cancellationToken)
{
var tokenTask = _medicalCheckServiceHelper.GetServiceToken(cancellationToken);
var medicalProvidersTask = _medicalProviderRepo.GetMedicalProvidersNames();
var token = await tokenTask;
var checkResults = await Task.WhenAll(request.UuidList.Select(uuid => _medicalCheckServiceHelper.GetResultAsync(uuid, token, cancellationToken)));
var medicalProviders = await medicalProvidersTask;
var customers = await _customerService.GetByIdsAsync(customerIds);
return await ConsolidateReceiptsResult(medicalProviders, checkResults, customers);
}
i. taskA 取自于配置中心,也即它会走 HTTP 请求public async Task<ResultResponse> ValidateReceiptAsync(List<string> customerIds, ReceiptRequest request, CancellationToken cancellationToken)
{
var tokenTask = _medicalCheckServiceHelper.GetServiceToken(cancellationToken);
var medicalProvidersTask = _medicalProviderRepo.GetMedicalProvidersNames();
var customersTask = _customerService.GetByIdsAsync(customerIds);
var token = await tokenTask;
var checkResultsTask = Task.WhenAll(request.UuidList.Select(uuid => _medicalCheckServiceHelper.GetResultAsync(uuid, token, cancellationToken)));
var medicalProviders = await medicalProvidersTask;
var customers = await customersTask;
var checkResults = await checkResultsTask;
return await ConsolidateReceiptsResult(medicalProviders, checkResults, customers);
}
但其实并不尽完善,因为这种写法的可读性并没有那么好,看起来更追求资源优化。