【问题标题】:Can 2 Linq Queries be run parallel?2个Linq查询可以并行运行吗?
【发布时间】:2018-08-06 16:30:32
【问题描述】:

我有 2 个 Linq 查询,第一个 Linq 查询返回 1148 条记录,第二个返回 6667 条记录。他们需要 8 分钟的时间来执行。有什么方法可以让它们在并行运行时更快?

var productbacklogworkitem =
               (from w in workItemcollectionList where w.Type.Name == "Product Backlog Item" select new {
                   Id = w.Id,
                   Name = w.Title,
                   FID = (w.WorkItemLinks.Count > 0) ? ((w.WorkItemLinks[0].LinkTypeEnd.Name.ToString() != "Child") ? w.WorkItemLinks[0].TargetId : 0) : 0,
                   Type = w.Type.Name,
                   State =w.State,
                   priorty = Convert.ToInt32(w.Fields["Priority"].Value),
                   Size = Convert.ToInt32(w.Fields["Effort"].Value),
                   StoryPoints = Convert.ToInt32(w.Fields["Story Points"].Value),
                   DoneStatus = w.Fields["Done Status"].Value.ToString(),
                   StoryOwner = w.Fields["Story Owner"].Value.ToString(),
                   Assignedto = w.Fields["Assigned To"].Value.ToString(),
                   StoryAuthor = w.Fields["Story Author"].Value.ToString(),
                   IterationPath = w.IterationPath
               }).ToList();
            var taskbugsworkitem =
             (from w in workItemcollectionList where (w.Type.Name == "Task" || w.Type.Name == "Bug") && (w.WorkItemLinks.Count > 0)   select new {
                 Id = w.Id,
                 Name = w.Title,
                 Type = w.Type.Name,
                 Storyid =  w.WorkItemLinks[0].TargetId,
                 status = w.State,
                 IterationPath = w.IterationPath,
                 Assignedto = w.Fields["Assigned To"].Value.ToString(),
                 priorty = Convert.ToInt32(w.Fields["Priority"].Value),
                 effort = Convert.ToInt32(w.Fields["effort"].Value),
                 Completed = (w.Type.Name== "Task") ? Convert.ToInt32(w.Fields["Completed"].Value):0
             }) .ToList();

【问题讨论】:

  • System.Threading.Tasks.Parallel.ForEach search for this 将您的代码调整为上述格式。这对这个问题很有用。
  • 为什么要通过一个查询从数据库中提取约 7000 条记录?
  • 碰巧有7k条记录@xxbbcc
  • @AkhilJain 您需要一次性提取所有数据吗?即使并行,它也不会突然大幅加速,除了随着数据的增长它可能会越来越慢。似乎这是实现一些分页的好地方,所以每次从数据库中加载 X 行。
  • @AkhilJain 你能说明workItemcollectionList 是什么以及其中的项目类别吗?你可以省略一些东西,只要你有一个mcve 的例子。 Anupam Singh 的答案似乎不错,但可能由于缺少上下文而失败。

标签: c# multithreading linq tfs-workitem plinq


【解决方案1】:

您也可以使用Task 进行两个并行查询。

Task<ResultClass1> t1 = Task<ResultClass1>.Run(() =>
    {
        var productbacklogworkitem =
        (from w in workItemcollectionList
         where w.Type.Name == "Product Backlog Item"
         select new ResultClass1
        {
            Id = w.Id,
            Name = w.Title,
            FID = (w.WorkItemLinks.Count > 0) ? ((w.WorkItemLinks[0].LinkTypeEnd.Name.ToString() != "Child") ? w.WorkItemLinks[0].TargetId : 0) : 0,
            Type = w.Type.Name,
            State = w.State,
            priorty = Convert.ToInt32(w.Fields["Priority"].Value),
            Size = Convert.ToInt32(w.Fields["Effort"].Value),
            StoryPoints = Convert.ToInt32(w.Fields["Story Points"].Value),
            DoneStatus = w.Fields["Done Status"].Value.ToString(),
            StoryOwner = w.Fields["Story Owner"].Value.ToString(),
            Assignedto = w.Fields["Assigned To"].Value.ToString(),
            StoryAuthor = w.Fields["Story Author"].Value.ToString(),
            IterationPath = w.IterationPath
        }).ToList();

        return ResultClass1;
    });

Task<ResultClass2> t2 = Task<ResultClass2>.Run(() =>
    {
        var taskbugsworkitem =
            (from w in workItemcollectionList
            where (w.Type.Name == "Task" || w.Type.Name == "Bug") && (w.WorkItemLinks.Count > 0)
             select new ResultClass2
            {
                Id = w.Id,
                Name = w.Title,
                Type = w.Type.Name,
                Storyid = w.WorkItemLinks[0].TargetId,
                status = w.State,
                IterationPath = w.IterationPath,
                Assignedto = w.Fields["Assigned To"].Value.ToString(),
                priorty = Convert.ToInt32(w.Fields["Priority"].Value),
                effort = Convert.ToInt32(w.Fields["effort"].Value),
                Completed = (w.Type.Name == "Task") ? Convert.ToInt32(w.Fields["Completed"].Value) : 0
            }).ToList();

        return taskbugsworkitem;
    });

Task.WaitAll(t1, t2);

// get results from these
t1.Result;
t2.Result;

【讨论】:

    【解决方案2】:

    您可以尝试 PLINQ,在实体上使用 AsParallel()

    var productbacklogworkitem =
                   (from w in workItemcollectionList.AsParallel() where w.Type.Name == "Product Backlog Item" select new {
                       Id = w.Id,
                       Name = w.Title,
                       FID = (w.WorkItemLinks.Count > 0) ? ((w.WorkItemLinks[0].LinkTypeEnd.Name.ToString() != "Child") ? w.WorkItemLinks[0].TargetId : 0) : 0,
                       Type = w.Type.Name,
                       State =w.State,
                       priorty = Convert.ToInt32(w.Fields["Priority"].Value),
                       Size = Convert.ToInt32(w.Fields["Effort"].Value),
                       StoryPoints = Convert.ToInt32(w.Fields["Story Points"].Value),
                       DoneStatus = w.Fields["Done Status"].Value.ToString(),
                       StoryOwner = w.Fields["Story Owner"].Value.ToString(),
                       Assignedto = w.Fields["Assigned To"].Value.ToString(),
                       StoryAuthor = w.Fields["Story Author"].Value.ToString(),
                       IterationPath = w.IterationPath
                   }).ToList();
                var taskbugsworkitem =
                 (from w in workItemcollectionList.AsParallel() where (w.Type.Name == "Task" || w.Type.Name == "Bug") && (w.WorkItemLinks.Count > 0)   select new {
                     Id = w.Id,
                     Name = w.Title,
                     Type = w.Type.Name,
                     Storyid =  w.WorkItemLinks[0].TargetId,
                     status = w.State,
                     IterationPath = w.IterationPath,
                     Assignedto = w.Fields["Assigned To"].Value.ToString(),
                     priorty = Convert.ToInt32(w.Fields["Priority"].Value),
                     effort = Convert.ToInt32(w.Fields["effort"].Value),
                     Completed = (w.Type.Name== "Task") ? Convert.ToInt32(w.Fields["Completed"].Value):0
                 }) .ToList();
    

    更多信息见:https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/introduction-to-plinq

    【讨论】:

    • 获取错误集合已修改枚举操作可能无法执行
    • 抱歉,不确定这个问题。但您可以参考链接进行探索。
    猜你喜欢
    • 1970-01-01
    • 2019-08-25
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多