C# 这个方法是异步的吗?

C# 这个方法是异步的吗?,c#,asynchronous,task,httpclient,response,C#,Asynchronous,Task,Httpclient,Response,此方法使用.Result。这是否意味着任务不会异步运行?是否需要重构才能使每个令牌请求真正异步 public async Task<string> ReturnDataFromUrlAsync(List<List<KeyValuePair<string, string>>> listOfPostData) { string allTokens = ""; var client = new HttpClient {

此方法使用
.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;
}
public async任务ReturnDataFromUrlAsync(postData列表)
{
字符串allTokens=“”;
var client=新的HttpClient
{
BaseAddress=新Uri(“http://localhost:23081")
};
var downloadTasksQuery=listOfPostData.Select(postData=>
{
var content=newformurlencodedcontent(postData);
HttpResponseMessage response=client.PostAsync(“/Token”,content.).Result;
var responseBodyAsText=response.Content.ReadAsStringAsync();
返回响应ebodyastext;
});
List downloadstasks=downloadstasksquery.ToList();
while(downloadTasks.Count>0)
{
Task firstFinishedTask=等待任务。WhenAny(下载任务);
下载任务。删除(firstFinishedTask);
//等待完成任务。
字符串内容=等待firstFinishedTask;
allTokens=allTokens+内容;
}
返回所有代币;
}

因此,目前这个电话:

HttpResponseMessage response = client.PostAsync("/Token", content).Result;
将导致调用线程暂停并等待结果。如果将wait关键字置于
client.PostAsync
之前,则会导致调用线程返回到调用方,并在操作完成后恢复。由于这是在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关键字将推断返回类型必须是Task类型,并且由于我们也在选择字符串,它的类型将是
IEnumerable

我还注意到:

var responseBodyAsText = response.Content.ReadAsStringAsync();
我认为造成这种混乱的原因是,这条语句实际上返回的是一个任务而不是字符串(如果使用
var
,请小心命名对象)


我们可以再次将wait关键字放在
response.Content
之前,返回键将自动推断。然后,我们可以在linq查询中选择字符串,而不是
任务

Hi@William我如何更改响应。Content.ReadAsStringAsync();所以它返回一个任务?例如,Task responseBodyAsText=await response.Content.ReadAsStringAsync();不起作用。是的,它不起作用,因为
await
解压
ReadAsStringAsync()
的结果,所以确实需要
string responseBodyAsText=await response.Content.ReadAsStringAsync()
如果没有wait关键字,它将返回
任务
,无论我做什么,如果我不使用。结果没有返回任何数据!您的提示非常好,但目前我仍然无法删除。结果您是否已将wait关键字放在客户端之前。PostAsync?。这是自动从methodYes中获取结果。但我必须删除wait并重新添加.Result以获取数据