这个方法是异步的吗?

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>