具有进度更新的并行I / O查询

时间:2015-03-09 14:51:18

标签: c# asynchronous parallel-processing asp.net-mvc-5 task-parallel-library

我有一个mvc5控制器,它消耗两个分页的远程数据服务。必须串联调用这两个服务 - 当从serviceA返回一页数据时,必须将其发送到serviceB。我的完全连续实现看起来像这样:

var pageNumber = 1;
var totalPages = x;
var results = new List<ProcessedResult>();
do {
    // Get results from service A.
    var initialResults = await serviceA.GetDataPageAsync(pageNumber);

    // Send serviceA's results to service B
    var processedResults = await serviceB.ProcessAsync(initialResults );

    // Save this iteration's results to our result collection.
    results.AddRange(processedResults); 

    //Report our progress so far
    ReportProgress((float)(pageNumber/totalPages)*100);

} while (pageNumber<totalPages);

return View(results)

如何在不中断延续(serviceB跟随每个页面的serviceA)或进度报告的情况下,如何并行(或异步)查询“页面”?感谢。

1 个答案:

答案 0 :(得分:2)

您可以使用TPL Dataflow。您可以使用其操作和选项(例如MaxDegreeOfParallelism)创建每个块,并使用LinkTo将它们连接在一起:

var aBlock = new TrasnformBlock<int, InitalResult>(
    pageNumber =>  serviceA.GetDataPageAsync(pageNumber),
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5});
var bBlock = new TrasnformBlock<InitalResult, ProcessedResult>(async initialResult =>  
{
    var result = await serviceB.ProcessAsync(initialResult);
    // ReportProgress
    return result;
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5});   

aBlock.LinkTo(bBlock, new DataflowLinkOptions { PropagateCompletion = true })

for (int pageNumber = 1; pageNumber < totalPages; pageNumber++)
{
    aBlock.Post(pageNumber);
}

aBlock.Complete();
await aBlock.Completion;