C# C/Tfs API-怪异并行。Foreach错误:集合已修改;枚举不能执行

C# C/Tfs API-怪异并行。Foreach错误:集合已修改;枚举不能执行,c#,foreach,tfs,tfs-sdk,parallel.foreach,C#,Foreach,Tfs,Tfs Sdk,Parallel.foreach,提醒一下: 我知道,在使用foreach循环进行迭代时,使用List中的foreach或Parallel.foreach不可能从集合中添加或删除项。这不是我想要做的 我想做的是: 我想迭代TFS工作项数组并创建每个项的副本 如果没有并行化,代码就可以正常工作 这有什么奇怪的: System.InvalidOperationException出现错误消息 收集被修改;枚举不能执行 如果我想并行执行它,就会抛出 但并非总是如此,有时代码并行执行得很好。 但我想不出一个模式 守则: 正如您所看到的,代

提醒一下:

我知道,在使用foreach循环进行迭代时,使用List中的foreach或Parallel.foreach不可能从集合中添加或删除项。这不是我想要做的

我想做的是:

我想迭代TFS工作项数组并创建每个项的副本

如果没有并行化,代码就可以正常工作

这有什么奇怪的:

System.InvalidOperationException出现错误消息

收集被修改;枚举不能执行

如果我想并行执行它,就会抛出

但并非总是如此,有时代码并行执行得很好。 但我想不出一个模式

守则:

正如您所看到的,代码非常简单。我甚至没有访问循环中的集合。 我尝试了很多不同的方法,创建了一个新的列表,使用System.Collections.Concurrent namsepace等类,但我不知道列表在哪里被修改。或者甚至是我的列表引发了异常

我希望有人能明白这一点,因为这将大大缩短执行时间

干杯

编辑:

正如我提到的:我已经尝试在迭代之前创建一个新列表。Parallel.ForEachcloneBatch.ToList,po,…->同样的结果

此外,我还更新了代码,以便大家可以看到IEnumerable的来源

编辑2:


如果我不使用复制的.Save语句,我仍然会在运行并行操作之前处理异常

,尝试迭代cloneBatch并在每个工作项上运行OpenPartial方法。就这样


我在浏览修订历史时遇到了同样的问题,没有修改任何东西。我认为访问历史必须以某种方式修改WorkItemCollection,这会导致异常。在任何情况下,在每个工作项上运行OpenPartial,即使它需要更多的时间和占用更多的内存,也为我解决了这个问题。

正如soja所说,我尝试使用.PartialOpen,但没有成功。但是,使用.Open确实有效

List<string> projectList = ConfigurationManager.AppSettings["Projects"].Split(',').ToList();

foreach (string project in projectList)
{
    Uri uri = new Uri(ConfigurationManager.AppSettings["TFSURI"] + "//" + project);

    TfsTeamProjectCollection tfsTeamProjectCollection = new TfsTeamProjectCollection(uri);
    WorkItemStore workItemStore = tfsTeamProjectCollection.GetService<WorkItemStore>();
    WorkItemCollection workItemCollection = workItemStore.Query("SELECT * FROM WorkItems");

    Parallel.For(0, workItemCollection.Count, (i) =>
    {
       workItemCollection[i].Open();
       WorkItem.ProcessWorkItem(project, workItemCollection[i]);
    });
}
请注意,WorkItem是一个单独的类,设计用于处理单个工作项。

复制的是什么。保存的是什么?什么类是IEnumberable?是否可能在保存新工作项时进行自我更新?
List<string> projectList = ConfigurationManager.AppSettings["Projects"].Split(',').ToList();

foreach (string project in projectList)
{
    Uri uri = new Uri(ConfigurationManager.AppSettings["TFSURI"] + "//" + project);

    TfsTeamProjectCollection tfsTeamProjectCollection = new TfsTeamProjectCollection(uri);
    WorkItemStore workItemStore = tfsTeamProjectCollection.GetService<WorkItemStore>();
    WorkItemCollection workItemCollection = workItemStore.Query("SELECT * FROM WorkItems");

    Parallel.For(0, workItemCollection.Count, (i) =>
    {
       workItemCollection[i].Open();
       WorkItem.ProcessWorkItem(project, workItemCollection[i]);
    });
}