包含2个以上列表的列表在循环中运行缓慢我可以使用Thread来加快速度吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了包含2个以上列表的列表在循环中运行缓慢我可以使用Thread来加快速度吗?相关的知识,希望对你有一定的参考价值。

这是我的代码,其中列表包含另外2个列表,其中WorkItem集合包含大量记录,例如7,000 it takes 10 min。有没有办法让它更快,在case它决定workItem类型,如果它是一个错误,任务或产品积压项目。请告诉我如何使循环更快。我们花了10分钟来循环7,000条记录,我们可以使用threading来加快速度吗? 已经试过parallel.for锁定workitemlist但得到错误。“没有找到序列”

public void GetProjectInfo(string projectname)
{
    string querystring = string.Format("select [System.Id], [System.Title],[Story.Author],[Story.Owner],[System.AssignedTo]," +
                    " [System.WorkItemType],[Microsoft.VSTS.Scheduling.StoryPoints],[Microsoft.VSTS.Common.Priority]," +
                    "[Microsoft.VSTS.Scheduling.Effort], [Actual.Effort.Completed]" +
                    ",[System.State]," +
                        public void GetProjectInfo(string projectname)
                    "[System.IterationPath]" +
                    " FROM WorkItemLinks" +
                    " WHERE" +
                    " ([Source].[System.TeamProject]='{0}'" +
                    " and [Source].[System.WorkitemType] IN ('Feature', 'Bug', 'Product Backlog Item', 'Task')" +
                    ")" + " and ([System.Links.LinkType]='System.LinkTypes.Hierarchy-Forward')" +
                    " ORDER BY [System.Id] " +  " mode (Recursive)", projectname);
    GetWorkItemTree(querystring);
}

private void GetWorkItemTree(string query)
{
    var treeQuery = new Microsoft.TeamFoundation.WorkItemTracking.Client.Query(_workitemstore, query);
    var links = treeQuery.RunLinkQuery();

    var workItemIds = links.Select(l => l.TargetId).ToArray();

    query = "SELECT * FROM WorkItems";
    var flatQuery = new Microsoft.TeamFoundation.WorkItemTracking.Client.Query(_workitemstore, query, workItemIds);
    var workItemCollection1 = flatQuery.RunQuery();

    var workItemList = new List<WorkItemViewModel>();

    for (int i = 0; i < workItemCollection.Count; i++)
    {
        var workItem = workItemCollection[i];

        if (workItem.Type.Name == "Product Backlog Item")
        {
            var model = new WorkItemViewModel()
            {
                FID = (workItem.WorkItemLinks.Count > 0) ? ((workItem.WorkItemLinks[0].LinkTypeEnd.Name.ToString() != "Child") ? workItem.WorkItemLinks[0].TargetId : 0) : 0,

                ID = workItem.Id,
                Name = workItem.Title,
                State = workItem.State,

                priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                //   Size =(int) workItem.Fields["Size"].Value ,
                Size = Convert.ToInt32(workItem.Fields["Effort"].Value),

                StoryPoints = Convert.ToInt32(workItem.Fields["Story Points"].Value),
                DoneStatus = workItem.Fields["Done Status"].Value.ToString(),
                StoryOwner = workItem.Fields["Story Owner"].Value.ToString(),
                Assignedto = workItem.Fields["Assigned To"].Value.ToString(),
                StoryAuthor = workItem.Fields["Story Author"].Value.ToString(),
                IterationPath = workItem.IterationPath
            };

            workItemList.Add(model);
        }
        else
        {
            switch (workItem.Type.Name)
            {
                case "Task":
                    var task = new TFSTask()
                    {
                        Storyid = (workItem.WorkItemLinks.Count > 0) ? workItem.WorkItemLinks[0].TargetId : 0,
                        ID = workItem.Id,
                        name = workItem.Title,
                        //activity = workItem.Fields["MyCompany.Activity"].Value.ToString(),
                        //start = (DateTime?)workItem.Fields["MyCompany.ActivityStart"].Value,
                        //due = (DateTime?)workItem.Fields["MyCompany.ActivityFinish"].Value,
                        status = workItem.State,
                        IterationPath = workItem.IterationPath,
                        Assignedto = workItem.Fields["Assigned To"].Value.ToString(),

                        priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                        effort = Convert.ToInt32(workItem.Fields["effort"].Value),
                        Completed = Convert.ToInt32(workItem.Fields["Completed"].Value)

                    };

                    if (task.Storyid != 0)
                    {
                        workItemList.Last().Tasks.Add(task);
                    }
                    break;
                case "Bug":
                    var bug = new TFSIssue()
                    {
                        Storyid = (workItem.WorkItemLinks.Count > 0) ? workItem.WorkItemLinks[0].TargetId : 0,
                        ID = workItem.Id,
                        Name = workItem.Title,
                        //start = (DateTime?)workItem.Fields["MyCompany.ActivityStart"].Value,
                        //due = (DateTime?)workItem.Fields["MyCompany.ActivityFinish"].Value,
                        State = workItem.State,
                        IterationPath = workItem.IterationPath,
                        Assignedto = workItem.Fields["Assigned To"].Value.ToString(),

                        priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                        effort = Convert.ToInt32(workItem.Fields["effort"].Value),
                        // Completed = Convert.ToInt32(workItem.Fields["Completed"].Value)
                    };
                    if (bug.Storyid != 0)
                    {
                        workItemList.Last().Issues.Add(bug);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}

public class WorkItemViewModel
{
    public string Name { get; set; }
    public int ID { get; set; }

    public string State { get; set; }
    // public DateTime? due { get; set; }
    public int priorty { get; set; }
    public int Size { get; set; }
    //  public int effort { get; set; }
    public int StoryPoints { get; set; }
    public string DoneStatus { get; set; }
    public string StoryOwner { get; set; }
    public string Assignedto { get; set; }
    public string StoryAuthor { get; set; }
    public string IterationPath { get; set; }
    public int FID { get; set; }
    public List<TFSIssue> Issues { get; set; }
    public List<TFSTask> Tasks { get; set; }

    public WorkItemViewModel()  // Added a public constructor
    {
        Issues = new List<TFSIssue>();
        Tasks = new List<TFSTask>();          
    }
}

public class TFSIssue
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime? Created { get; set; }

    public string State { get; set; }
    public DateTime? due { get; set; }
    public string IterationPath { get; set; }
    public string Assignedto { get; set; }
    public int priorty { get; set; }
    public int effort { get; set; }
    public int Storyid { get; set; }
    //  public int Completed { get; set; }
}

public class TFSTask
{
    public int ID { get; set; }
    public string name { get; set; }
    //  public string activity { get; set; }
    public string status { get; set; }
    //  public DateTime? start { get; set; }
    //  public DateTime? due { get; set; }
    public string IterationPath { get; set; }
    public string Assignedto { get; set; }
    public int priorty { get; set; }
    public int effort { get; set; }
    public int Completed { get; set; }
    public int Storyid { get; set; }
}
答案

尝试这样的事情:

var workItemList = new List<WorkItemViewModel>();

var t = workItemList.select(w => Task.Run(() => {
    // Put the work.
}));

await Task.WhenAll(t);
另一答案

这样的事情应该做:

IEnumerable<Data> LoadDataFromDatabase()
{ 
    return ...
}

void ProcessInParallel()
{
   while(true)
   {
      var data = LoadDataFromDatabase().ToList();

      if(!data.Any()) break;

      data.AsParallel().ForEach(ProcessSingleData);
   }
}

void ProcessSingleData(Data d)
{
  // do something with data
}
另一答案

好的,下一步不是简单地多线程。

您的代码运行缓慢,并且您已使用StopWatch对象尝试跟踪减速发生的位置。大!但是,你不能停留在100线长的For-Loop。在For循环中的时间是花费的时间?使用秒表来确定每个部分或每行上花费的每个循环的哪个部分。你应该可以说,“这一行每次花费100毫秒,超过7000个文档,这就是为什么它花了10分钟。”

现在,您可能处于慢速代码或慢速算法/解决问题的位置。你应该先付出努力来解决这个问题。然后弄清楚多线程是否会给你带来很好的改进。

另一答案

看来你可以在这里使用线程,

也许Parallel.For可以帮到你。

以上是关于包含2个以上列表的列表在循环中运行缓慢我可以使用Thread来加快速度吗?的主要内容,如果未能解决你的问题,请参考以下文章

Numpy 规范化代码异常缓慢

第 4 章 操作列表

带有循环的 UDF 非常缓慢且效率低下

使用 for 返回列表 10 次。我希望在每个循环中按顺序在屏幕上打印 2 个数字 [关闭]

如何使用 foreach 循环在列表中的短语之间添加分隔符?

包含 k 个列表中每个列表中至少一个元素的最小元素范围的时间复杂度