【发布时间】:2015-06-18 22:14:57
【问题描述】:
我花了大约 8 个多小时在网上搜索帮助,但我找不到任何东西,所以就这样吧。
我正在使用 Team Foundation Server 和 C#,我正在尝试获取工作项列表并将它们转换为我们制作的通用对象以绑定到特殊 UI。要工作的项目是特定日期的任务,列表大约有 30 多个项目,所以没什么大不了的。
循环如下所示:
List<IWorkItemData> workitems = new List<IWorkItemData>();
var queryForData = Store.Query(query).Cast<WorkItem>();
if (queryForData.Count() == 0)
return workitems;
Parallel.ForEach(queryForData, (wi) =>
{
var temp = wi;
lock (workitems)
{
TFSWorkItemData tfsWorkItem = new TFSWorkItemData(temp);
workitems.Add(tfsWorkItem);
}
});
TFSWorkItemData 的构造函数内部是这样的:
public TFSWorkItemData(WorkItem workItem)
{
this.workItem = workItem;
this.Fields = new Dictionary<string, IFieldData>();
// Add Fields
foreach (Field field in workItem.Fields)
{
TFSFieldData fieldData = new TFSFieldData
{
Value = field.Value,
OldValue = field.OriginalValue,
ReferenceName = field.ReferenceName,
FriendlyName = field.Name,
ValueType = field.FieldDefinition.SystemType
};
this.Fields.Add(field.ReferenceName, fieldData);
}
}
因此执行此操作大约需要 90 秒。我知道抓取 30 个工作项不需要那么长时间,所以这一定是我正在做的事情导致这需要这么长时间。我知道锁会影响性能,但是当我删除它时,我得到一个 InvalidOperationException 说集合已被修改。当我查看此异常的详细信息时,我能找到的唯一有用信息是该集合是一本字典。奇怪的是,在我看来,工作项中的字段字典根本没有被修改。而且我班上的字典只是被添加了,除非我遗漏了什么,否则这不应该是罪魁祸首。
请帮助我弄清楚我在字典方面做错了什么。我确实尝试将并行 foreach 循环移动到 workitem.Fields 集合,但我似乎无法让它工作。
编辑:阅读答案的 cmets 以获得此问题的答案。谢谢。
【问题讨论】:
-
您正在锁定列表。将项目添加到列表是并行任务所做的唯一事情。但是您正在锁定列表。 当然它会像连续剧一样。
-
还有,你不是说
new TFSWorkItemData (temp)吗? -
锁定列表是唯一可以防止我得到的 InvalidOperationException 的方法。感谢您的快速响应并指出错误。
-
请记住,Parallel.ForEach 不提供任何关于并行化程度的保证。
标签: c# tfs parallel-processing invalidoperationexception parallel.foreach