如何在Windows Phone上运行并行任务?

我正在构建一个WP8应用程序,我需要执行大约30个Web请求。 这些请求不依赖于彼此,因此可以并行化。

我的代码看起来像这样(简化/伪代码):

foreach (Uri uri in uris) { var rawData = await Task.Run(() => httpClient.GetStringAsync(uri).ConfigureAwait(false)); var processedData = dataProcessor.Process(rawData); processedDataCollection.Add(processedData); } 

当我看到Fiddler时,请求全部都是sequantial; 它需要几秒钟来执行和处理所有这些。 但是,我不希望代码等到1个请求完成后才转移到下一个请求,我想同时执行多个请求。

通常我会使用Parallel.Invoke()Parallel.ForEach()或类似的东西来执行此操作,但显然并行库在Windows Phone 8中不可用。

那么实现这一目标的最佳方法是什么? Task.Factory.StartNew()new Thread()

无需在单独的线程上运行每个请求。 您可以轻松地执行此操作:

 var raw = await Task.WhenAll(uris.Select(uri => httpClient.GetStringAsync(uri))); var processed = raw.Select(data => dataProcessor.Process(data)).ToArray(); 

此代码获取uris的集合并为每个代码启动HTTP下载( Select(...) )。 然后它异步地等待它们全部完成( WhenAll )。 然后在第二行代码中处理所有数据。

但是,Windows Phone运行时可能会限制您对同一服务器的最大请求数。

您正在使用await您创建的任务 – 这意味着您在继续该方法之前等待调用完成。 正如你所指出的那样,你的foreach没有并行化,所以你在这里做的是一些串行请求。

您可以(可能)打算使用Task.WaitAll方法进行此运行。 这样的东西应该足够了:

 var tasks = new List(); foreach (Uri uri in uris) { var thisTask = Task.Run(() => { httpClient.GetStringAsync(uri).ConfigureAwait(false); var processedData = dataProcessor.Process(rawData); processedDataCollection.Add(processedData); }); tasks.Add(thisTask); } Task.WaitAll(tasks); 

请注意,这也会并行处理您的数据(也就是说,它也将并行调用.Process ),而原始代码却没有。

我还要补充一点,你可能不想一次运行30个请求,除非他们是不同的服务器。 在同一台服务器上同时向Uris发出30个请求不太可能改善您的处理时间。 (幸运的是,TPL可能会为您解决这个问题,因为它会稍微限制并行性。)