简体   繁体   English

如何使用HttpClient()存储来自多个异步请求的返回数据,直到所有请求完成?

[英]How to store return data from multiple async requests using HttpClient() until all requests complete?

I need to iterate through a series of post requests for data from a url. 我需要遍历一系列来自网址的数据发布请求。 The requests need to be async. 请求需要异步。 What is the best way to check all returns have completed, and to store that data until all data returned? 检查所有返回已完成的最佳方法是什么,并存储该数据直到返回所有数据? Prefer to use HttpClient() 喜欢使用HttpClient()

Code snippet: 代码段:

     HttpContent httpContent = new FormUrlEncodedContent(postData);           
     HttpResponseMessage response =  client.PostAsync("/mydata", httpContent).Result; 

     var responsecode = (int)response.StatusCode; 

     if (response.IsSuccessStatusCode)
     {
         var responseBodyAsText = await response.Content.ReadAsStringAsync();
         return responseBodyAsText;
     }
     else
     {
         return responsecode +" " +response.ReasonPhrase; 
     }

` `

Well, first, bear in mind that you've got an async problem here: 好吧,首先,请记住,你在这里遇到了一个异步问题:

 HttpContent httpContent = new FormUrlEncodedContent(postData);           

 // whoops! .Result makes this line synchronous.
 HttpResponseMessage response =  client.PostAsync("/mydata", httpContent).Result;

 var responsecode = (int)response.StatusCode; 

 if (response.IsSuccessStatusCode)
 {
     var responseBodyAsText = await response.Content.ReadAsStringAsync();
     return responseBodyAsText;
 }
 else
 {
     return responsecode +" " +response.ReasonPhrase; 
 }

Next, since HttpClient gives you a Task<HttpResponseMessage> , it seems that you want to have all of the responses, as strings, as something like, say, a Task<IEnumerable<string>> , right? 接下来,由于HttpClient为您提供了一个Task<HttpResponseMessage> ,您似乎希望将所有响应作为字符串,例如,一个Task<IEnumerable<string>> ,对吧? We can easily write a function to turn a Task<HttpResponseMessage> into a Task<string> : 我们可以轻松编写一个函数来将Task<HttpResponseMessage>转换为Task<string>

public async Task<string> ReadResultAsync(Task<HttpResponseMessage> responseTask)
{
    var response = await responseTask;

    var responsecode = (int)response.StatusCode; 

    if (response.IsSuccessStatusCode)
    {
        var responseBodyAsText = await response.Content.ReadAsStringAsync();

        return responseBodyAsText;
    }
    else
    {
        return responsecode + " " + response.ReasonPhrase; 
    }
}

Now let's say you've got some collection of post data that you need to turn into this async collection of strings, called myData : 现在假设你有一些发布数据的集合,你需要转换成这个异步字符串集合,称为myData

// bear in mind, this code doesn't (necessarily) need to be in a
//  method marked "async". If you want to await on resultsTask, though,
//  it would need to be in an async method.

var tasks = myData
    .Select(x => new FormUrlEncodedContent(x)) //  IEnumerable<FormUrlEncodedContent>
    .Select(x => client.PostAsync("/mydata", x)) // IEnumerable<Task<HttpResponseMessage>>
    .Select(x => ReadResultAsync(x)) // IEnumerable<Task<string>>
    .ToArray(); // Task<string>[]

var resultsTask = Task.WhenAll(tasks); // here is Task<string[]>

write a an asynchronous function that fires your post data (i just used your code, please add correct error/exception handling): 写一个异步函数来激发你的帖子数据(我刚用过你的代码,请添加正确的错误/异常处理):

async Task<string> PostDataAsync(Dictionary<string, string> postData)
{
    var httpContent = new FormUrlEncodedContent(postData);           
    var response = await client.PostAsync("/mydata", httpContent).ConfigureAwait(false); 

    var responsecode = (int)response.StatusCode; 

    if (response.IsSuccessStatusCode)
    {
        var responseBodyAsText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        return responseBodyAsText;
    }
    else
    {
       return responsecode +" " +response.ReasonPhrase; 
    }
}

Now, let's say you have a list of post data 'List> postDataCollection`, then build your requests 现在,假设您有一个帖子数据列表'List> postDataCollection`,然后构建您的请求

var postRequests = postDataCollection.Select(pd => PostDataAsync(pd)).ToArray();

and then wait for all of them to finish 然后等待所有人完成

var postResponses = await Task.WhenAll(postRequests);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM