c# - 无法理解 async 的行为,在 c# 中等待
问题描述
我正在学习 c# 的 await async 功能。但是下面代码的行为让我感到困惑。
public static async Task CreateMultipleTasksAsync() {
HttpClient client = new HttpClient() {
MaxResponseContentBufferSize = 1000000
};
Task <int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
Task <int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
int length1 = await download1;
int length2 = await download2;
Console.WriteLine("Sum is {0}", length1 + length2);
}
public static async Task <int> ProcessUrlAsync(string url, HttpClient client) {
Console.WriteLine("I am here to process {0}", url);
var byteArray = await client.GetByteArrayAsync(url);
Console.WriteLine("processing is completed {0}", url);
return byteArray.Length;
}
我期待的是在完成 download1 和 download2 后 CreateMultipleAsync() 的最后一行将执行并打印长度总和。问题是最后一行永远不会执行!
解决方案
这是因为您在构造函数中使用了异步方法。从这里删除它。
另外,不要使用async void
. 相反,您应该使用async Task
:
class MultipleAsync
{
public async Task StartMultiple()
{
await CreateMultipleTasksAsync();
}
public static async Task CreateMultipleTasksAsync()
{
HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };
Task<int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
Task<int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
int length1 = await download1;
int length2 = await download2;
Console.WriteLine("Sum is {0}", length1 + length2);
}
public static async Task<int> ProcessUrlAsync(string url, HttpClient client)
{
Console.WriteLine("I am here to process {0}", url);
var byteArray = await client.GetByteArrayAsync(url);
Console.WriteLine("processing is completed {0}", url);
return byteArray.Length;
}
}
用法:
MultipleAsync multipleAsync = new MultipleAsync();
await multipleAsync.StartMultiple();
此外,由于您的第二个任务不依赖于第一个任务的结果,您可以并行运行两个任务。第二个任务不会等待第一个任务完成:
HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };
Task<int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
Task<int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
var lengthts = await Task.WhenAll(download1, download2);
Console.WriteLine("Sum is {0}", lengthts.Sum());
推荐阅读
- html - CSS:文本输入在选中时有另一个边框
- node.js - Node.js:CSV 在 mac os(数字)上正确显示,但在 windows(excel)上显示全部混乱
- python - 将 CNN 的输出传递给 BILSTM
- python - 将列表中的值映射到没有时间顺序的已知字典格式
- c# - 如何在 docker 容器中运行这个 PowerShell 脚本?
- google-apps-script - Google Apps 脚本执行时间问题
- c# - 如何将配置部分传递给库项目中的 services.Configure()?
- javascript - JavaScript Date.getFullYear() returnin Nan - 仅在 FireFox 中
- javascript - 如果在给定的时间范围内多次调用相同的方法,则取消旧的 Promise.resolve
- python - 如何使用 Ansible 记录 ansible_python_interpreter 失败的 IP?