UWP应用程序中的并行httprequest

时间:2016-04-30 16:10:11

标签: http win-universal-app httpclient

我正在创建一个需要todo并行http请求的应用程序,我正在使用HttpClient。 我正在遍历网址和foreach URl我开始一个新的任务todo请求。 在循环之后,我等待直到每个任务完成。 但是,当我检查使用fiddler进行的调用时,我看到请求是同步调用的。它不像是一堆请求,而是一个接一个。 我搜索了一个解决方案,发现其他人也经历过这个,但不是UWP。解决方案是增加ServicePointManager上的DefaultConnectionLimit。 问题是UWP不存在ServicePointManager。我查看了API,我想我可以在HttpClientHandler上设置DefaultConnectionLimit,但是没有。

所以我有几个问题。 DefaultConnectionLimit仍然是可以在某处设置的属性吗? 如果是的话,我在哪里设置它? 如果没有,我该如何增加连接限制? UWP中是否还有连接限制?

这是我的代码:

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());

这是请求:

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

2 个答案:

答案 0 :(得分:0)

欧客。我有解决方案。我确实需要在任务中使用async / await。问题是我使用StartNew而不是Run。但我必须使用StartNew,因为我正在通过一个州。 随着StartNew。除非您调用Unwrap,否则不会等待任务内部的任务。所以Task.StartNew(.....)。解包()。这样Task.WhenAll()将等待内部任务完成。 当你使用Task.Run()时,你不必这样做。

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());

答案 1 :(得分:0)

我认为解决此问题的简便方法不是“手动”启动请求,而是使用带有异步委托的linq来查询情节,然后再进行设置。

您基本上将其分为两个步骤:

  1. 获取所有下一集
  2. 在每个中设置它们

这还具有将查询代码与设置节目的副作用脱钩的好处。

        var shows = Enumerable.Range(0, 10).Select(x => new Show());
        var client = new HttpClient();

        (Show, Episode)[] nextEpisodes = await Task.WhenAll(shows
            .Select(async show =>
                (show, await GetEpisodeAsync(show.NextEpisodeUri, client))));

        foreach ((Show Show, Episode Episode) tuple in nextEpisodes)
        {
            tuple.Show.NextEpisode = tuple.Episode;
        }

请注意,我正在使用C#7的新元组语法。如果不可用,请相应地更改为旧的元组语法。