这个方法是异步的吗?
Is this method asynchronous?
此方法使用.Result
。这是否意味着任务不会 运行 异步?是否需要重构才能使每个令牌请求真正异步?
public async Task<string> ReturnDataFromUrlAsync(List<List<KeyValuePair<string, string>>> listOfPostData)
{
string allTokens = "";
var client = new HttpClient
{
BaseAddress = new Uri("http://localhost:23081")
};
var downloadTasksQuery = listOfPostData.Select(postData =>
{
var content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = client.PostAsync("/Token", content).Result;
var responseBodyAsText = response.Content.ReadAsStringAsync();
return responseBodyAsText;
});
List<Task<string>> downloadTasks = downloadTasksQuery.ToList();
while (downloadTasks.Count > 0)
{
Task<string> firstFinishedTask = await Task.WhenAny(downloadTasks);
downloadTasks.Remove(firstFinishedTask);
// Await the completed task.
string content = await firstFinishedTask;
allTokens = allTokens + content;
}
return allTokens;
}
所以目前这个电话:
HttpResponseMessage response = client.PostAsync("/Token", content).Result;
会导致调用线程停顿并等待结果。如果将 await 关键字放在 client.PostAsync
之前,它将导致调用线程 return 到调用者并在操作完成后恢复。由于这是在 linq 查询中完成的,因此您需要像这样使 lambda 表达式异步:
var downloadTasksQuery = listOfPostData.Select(async postData =>
{
var content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.PostAsync("/Token", content);
var responseBodyAsText = await response.Content.ReadAsStringAsync();
return responseBodyAsText;
});
在 lambda 表达式中附加 async 关键字将推断 return 类型必须是 Task 类型,因为我们也是 selecting 字符串,它将是 [=14= 类型]
我也注意到了这一点:
var responseBodyAsText = response.Content.ReadAsStringAsync();
我认为混淆的原因是因为这个语句实际上是 returning 一个任务而不是一个字符串(如果你使用 var
请注意你命名的东西)
我们可以再次将 await 关键字放在 response.Content
之前,然后 return 键将被自动推断出来。然后我们可以 select 字符串,在 linq 查询中而不是 Task<string>
此方法使用.Result
。这是否意味着任务不会 运行 异步?是否需要重构才能使每个令牌请求真正异步?
public async Task<string> ReturnDataFromUrlAsync(List<List<KeyValuePair<string, string>>> listOfPostData)
{
string allTokens = "";
var client = new HttpClient
{
BaseAddress = new Uri("http://localhost:23081")
};
var downloadTasksQuery = listOfPostData.Select(postData =>
{
var content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = client.PostAsync("/Token", content).Result;
var responseBodyAsText = response.Content.ReadAsStringAsync();
return responseBodyAsText;
});
List<Task<string>> downloadTasks = downloadTasksQuery.ToList();
while (downloadTasks.Count > 0)
{
Task<string> firstFinishedTask = await Task.WhenAny(downloadTasks);
downloadTasks.Remove(firstFinishedTask);
// Await the completed task.
string content = await firstFinishedTask;
allTokens = allTokens + content;
}
return allTokens;
}
所以目前这个电话:
HttpResponseMessage response = client.PostAsync("/Token", content).Result;
会导致调用线程停顿并等待结果。如果将 await 关键字放在 client.PostAsync
之前,它将导致调用线程 return 到调用者并在操作完成后恢复。由于这是在 linq 查询中完成的,因此您需要像这样使 lambda 表达式异步:
var downloadTasksQuery = listOfPostData.Select(async postData =>
{
var content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.PostAsync("/Token", content);
var responseBodyAsText = await response.Content.ReadAsStringAsync();
return responseBodyAsText;
});
在 lambda 表达式中附加 async 关键字将推断 return 类型必须是 Task 类型,因为我们也是 selecting 字符串,它将是 [=14= 类型]
我也注意到了这一点:
var responseBodyAsText = response.Content.ReadAsStringAsync();
我认为混淆的原因是因为这个语句实际上是 returning 一个任务而不是一个字符串(如果你使用 var
请注意你命名的东西)
我们可以再次将 await 关键字放在 response.Content
之前,然后 return 键将被自动推断出来。然后我们可以 select 字符串,在 linq 查询中而不是 Task<string>