首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化并行选择导致并行执行

优化并行选择导致并行执行
EN

Stack Overflow用户
提问于 2015-01-08 09:39:16
回答 1查看 63关注 0票数 1

我试图找到执行以下流的最佳方法

  1. 从流中获取X标识符的列表
  2. 对于每个X标识符,转到DB并使用复杂查询获得Y标识符列表(应该与并行)
  3. 合并列表并区分它
  4. 对于每一个Y标识符,执行一个长时间运行的任务(应该并行)

2-4中的所有流都应该在一个与1不同的线程中完成,因此一旦动作1调用操作2,它就会继续做其他事情。

目前,我的流看起来是这样的(这是2-4,在1之后调用):

代码语言:javascript
复制
private void PerformActionAsync(List<long> XIds)
{
     var affectedYIds = XIds.AsParallel().SelectMany(xId =>
     {
         return GetAffectedYIdsLongRunning(xId);   

     }).Distinct();

     affectedYIds.ForAll(yId=>
     {
         ExcuteLongRunningAction(yId);
     });
 }

这不能工作,因为SelectMany和ForAll仍然阻塞调用线程,我可以用新的任务创建替换ForAll,但是SelectMany仍然会阻塞调用线程。如何以真正的异步方式执行SelectMany?

目前,我最好的解决方案是用Taks.Run包装整个方法实现,问题是是否有更好的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-08 12:08:39

您可以将代码包装在Task.Run中并返回该任务。这将使一切在后台运行。

下面的单元测试显示了使用情况:

代码语言:javascript
复制
[TestClass]
public class PLinqTests
{
    private static readonly Stopwatch Watch = Stopwatch.StartNew();

    [TestMethod]
    public async Task TestPerformAsync()
    {
        await PerformActionAsync(Enumerable.Range(0, 10));
    }

    private Task PerformActionAsync(IEnumerable<int> xIds)
    {
        return Task.Run(() =>
        {
            var affectedYIds = xIds
                .AsParallel()
                .WithDegreeOfParallelism(5)
                .SelectMany(this.GetAffectedYIdsLongRunning)
                .Distinct();

            affectedYIds.ForAll(this.ExcuteLongRunningAction);
        });
    }

    private void ExcuteLongRunningAction(int yId)
    {
        Thread.Sleep(1000);
        Console.WriteLine("Executed {0} at {1}.", yId, Watch.Elapsed.Seconds);
    }

    private IEnumerable<int> GetAffectedYIdsLongRunning(int xId)
    {
        Thread.Sleep(1000);
        Console.WriteLine("Getting Affected for {0} at {1}.", xId, Watch.Elapsed.Seconds);

        return Enumerable.Range(30, 10);
    }
}

输出:

代码语言:javascript
复制
Getting Affected for 0 at 1.
Getting Affected for 1 at 1.
Getting Affected for 2 at 1.
Getting Affected for 4 at 2.
Getting Affected for 3 at 2.
Getting Affected for 5 at 2.
Getting Affected for 6 at 2.
Getting Affected for 7 at 3.
Getting Affected for 8 at 3.
Getting Affected for 9 at 3.
Executed 32 at 3.
Executed 31 at 3.
Executed 30 at 4.
Executed 34 at 4.
Executed 33 at 4.
Executed 37 at 4.
Executed 36 at 4.
Executed 35 at 5.
Executed 39 at 5.
Executed 38 at 5.
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27836955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档