Search code examples
httpwin-universal-apphttpclient

Parallel httprequest in UWP app


I'm creating an app that requires todo parallel http request, I'm using HttpClient for this. I'm looping over the urls and foreach URl I start a new Task todo the request. after the loop I wait untill every task finishes. However when I check the calls being made with fiddler I see that the request are being called synchronously. It's not like a bunch of request are being made, but one by one. I've searched for a solution and found that other people have experienced this too, but not with UWP. The solution was to increase the DefaultConnectionLimit on the ServicePointManager. The problem is that ServicePointManager does not exist for UWP. I've looked in the API's and I thought I could set the DefaultConnectionLimit on HttpClientHandler, but no.

So I have a few Questions. Is DefaultConnectionLimit still a property that could be set somewhere? if so, where do i set it? if not, how do I increase the connnectionlimit? Is there still a connectionlimit in UWP?

this is my code:

var requests = new List<Task>();
var client = GetHttpClient();
foreach (var show in shows)
{
   requests.Add(Task.Factory.StartNew((x) =>
   {
      ((Show)x).NextEpisode = GetEpisodeAsync(((Show)x).NextEpisodeUri, client).Result;}, show));
   }
}
await Task.WhenAll(requests.ToArray());

and this is the request:

public async Task<Episode> GetEpisodeAsync(string nextEpisodeUri, HttpClient client)
{
    try
    {
        if (String.IsNullOrWhiteSpace(nextEpisodeUri)) return null;
        HttpResponseMessage content; = await client.GetAsync(nextEpisodeUri);
        if (content.IsSuccessStatusCode)
        {
            return JsonConvert.DeserializeObject<EpisodeWrapper>(await content.Content.ReadAsStringAsync()).Episode;
        }
    }
    catch (Exception ex)
    {

        Debug.WriteLine(ex.Message);
    }

    return null;
}

Solution

  • Oke. I have the solution. I do need to use async/await inside the task. The problem was the fact I was using StartNew instead of Run. but I have to use StartNew because i'm passing along a state. With the StartNew. The task inside the task is not awaited for unless you call Unwrap. So Task.StartNew(.....).Unwrap(). This way the Task.WhenAll() will wait untill the inner task is complete. When u are using Task.Run() you don't have to do this.

    Task.Run vs Task.StartNew

    The stackoverflow answer

    var requests = new List<Task>();
    var client = GetHttpClient();
    foreach (var show in shows)
    {
        requests.Add(Task.Factory.StartNew(async (x) =>
        {
            ((Show)x).NextEpisode = await GetEpisodeAsync(((Show)x).NextEpisodeUri, client);
        }, show)
        .Unwrap());
    }
    Task.WaitAll(requests.ToArray());