2015-11-18 28 views
3

我需要遍历一系列来自url的数据请求。这些请求需要是异步的。检查所有退货的最佳方法是什么完成,并存储该数据,直到返回所有数据?喜欢使用的HttpClient()如何使用HttpClient()从多个异步请求中存储返回数据,直到所有请求完成?

代码片段:

 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; 
    } 

`

回答

1

嗯,首先,请记住,你已经有了一个异步问题就在这里:

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; 
} 

其次,由于HttpClient给你一个Task<HttpResponseMessage>,好像你想要把所有的回答作为字符串,比如说Task<IEnumerable<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; 
    } 
} 

现在让我们假设你有后的一些数据收集,你需要转成字符串这个异步集合,称为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[]> 
+0

Hi FMM When I调用var tasks = myData。选择...它是否需要在parallel.foreach循环或简单的foreach循环中?然后在循环结束后调用var resultsTask = Task ... – Steve

+0

没有理由使用并行foreach循环,除非在该集合中有足够的项目需要将它们分发到多个核心。 – FMM

+0

你好,你能够更详细地概述你如何建立链接声明?另外,主要优先级,可以调用var本身不是异步的方法调用var resulsTask? (以避免一连串的方法成为异步!)Ta – Steve

0

写了一个触发您的文章(我只是用你的代码,请填入正确的错误/异常处理)异步函数:

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; 
    } 
} 

现在,让我们说你有发布数据“名单> postDataCollection`的列表,然后建立您的要求

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

,然后等待他们全部完成

var postResponses = await Task.WhenAll(postRequests); 
+0

嗨esskar你有没有使用字典的速度? – Steve

+0

@Steve,不,我刚刚检查了构造函数文档https://msdn.microsoft.com/en-us/library/system.net.http.formurlencodedcontent.formurlencodedcontent(v=vs.118).aspx – esskar

相关问题