gpt4 book ai didi

C#/Tfs-API - 奇怪的 Parallel.Foreach 错误 : Collection was modified; enumeration may not execute

转载 作者:行者123 更新时间:2023-11-30 21:58:42 26 4
gpt4 key购买 nike

注意事项:

我知道在使用 foreach-loop 迭代时无法从集合中添加或删除项目, 通过使用 ForEeach()List<T>Parallel.ForEach() .那不是我想要做的。

我想做什么:

我想遍历一个 TFS 数组- WorkItems并创建每个项目的副本。

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

这有什么奇怪的:

System.InvalidOperationException带有错误信息

Collection was modified; enumeration may not execute"

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

但并非总是如此,有时代码可以并行执行。但是我想不出一个模式...

代码:

    public void Clone(string area, string sourceIteration, string targetIteration, bool includeSubIterations)
{
WorkItemCollection wisToCopy = getWorkItems(area, sourceIteration, includeSubIterations);
IEnumerable<WorkItem> wiToCopyList = (from WorkItem mItem in wisToCopy select mItem).ToList();
internalCloning(wiToCopyList, targetIteration);
}


private WorkItemCollection getWorkItems(string areaPath, string iterationPath, bool inlcudeSubIterations)
{
if (inlcudeSubIterations)
{
return _wis.Query(@"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '" + _prj + @"' AND [System.AreaPath] UNDER '" + areaPath + "' AND [System.IterationPath] UNDER '" + iterationPath + "'");
}
return _wis.Query(@"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '" + _prj + @"' AND [System.AreaPath] UNDER '" + areaPath + "' AND [System.IterationPath] = '" + iterationPath + "'");
}


private void internalCloning(IEnumerable<WorkItem> cloneBatch, string targetIteration)
{
var po = new ParallelOptions();
// if i put'1' here everything works as expected
po.MaxDegreeOfParallelism = 4;
Parallel.ForEach(cloneBatch, po, wi =>
{
WorkItem copied = wi.Copy(wi.Type, WorkItemCopyFlags.CopyFiles);
copied.Links.Clear();
copied.IterationPath = targetIteration;
copied.Save();

copied.State = wi.State;
copied.Save();
});
}

如您所见,代码非常简单。我什至没有访问循环内的集合。我尝试了很多不同的东西,创建一个新列表,使用 System.Collections.Concurrent 的类namsepace 等。但我只是不知道列表在哪里被修改。 (或者甚至是我的列表抛出异常?)

我希望有人能解决这个问题,因为它会大大缩短执行时间。

干杯。

编辑:

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

此外,我已经更新了代码,这样你们就可以看到 IEnumerable 的来源。

编辑 2:

如果我离开 copied.Save()声明出来,我仍然得到异常

最佳答案

我尝试使用 .PartialOpen() 作为 soja 指出但不成功。但是,使用 .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 是一个单独的类,旨在处理单个工作项。

关于C#/Tfs-API - 奇怪的 Parallel.Foreach 错误 : Collection was modified; enumeration may not execute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29892191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com