代码:
Parallel.ForEach(
infoMap,
map =>
{
var workItem = map.WorkItem;
var parentInViews = viewMaps;
var workbenchItem = map.WorkbenchItem;
string LinkType = string.Empty;
WorkItemLinkCollection linkedWorkItems = workItem.WorkItemLinkHistory;
if (linkedWorkItems != null && linkedWorkItems.Count > 0)
LinkType = linkedWorkItems[0].LinkTypeEnd.LinkType.ReferenceName;
else if (workItem != null)
LinkType = workItem.Store.WorkItemLinkTypes.LinkTypeEnds["Parent"].LinkType.ReferenceName;
if (!string.IsNullOrEmpty(LinkType))
{
var viewMap = parentInViews.FirstOrDefault();
if (viewMap != null)
{
var linkName = LinkType;
var childType = viewMap.ChildType;
ILinkItem itm = Factory.BuildLinkItem(linkName, workbenchItem, workbenchItem);
lock (Addparents)
{
Addparents.Add(itm);
}
}
}
});
Factory.BuildLinkItem
定义:
public static ILinkItem BuildLinkItem(string linkName, IWorkbenchItem parent, IWorkbenchItem child)
{
return new LinkItem { LinkName = linkName ?? string.Empty, Child = child, Parent = parent };
}
完全658 items
存在且执行上述Parallel.ForEach
功能几乎 10秒。
是否可以缩短执行时间,如果是,请建议我一个解决方案。感谢。
注意:除了Parallel.ForEach
之外,如果有任何备用方法可以提高性能并缩短执行时间,请提供建议。感谢。
答案 0 :(得分:1)
您的问题出在lock
声明中。与其他同步机制相比,它背后的mutex
机制非常昂贵。我打赌这10秒内99.99%,代码花费锁定并等待那个关键部分。即使非并行选择也会快得多。
您有两种选择。首先是使用.AsParallel()
.Select()
和.Where()
代替Parallel.ForEach
并添加到锁内的集合中。我强烈推荐这个。这样,就可以自动处理不同项目上的操作之间的同步。
第二个选项是使用.NET 4中存在的某种concurrent collection而不是锁定和正常集合。这些集合经过特别优化,可以快速添加项目,即线程安全。
这是一个小黑客,你怎么能简单地将其转换为AsParallel
:
infoMap.AsParallel().Select(
map =>
{
var workItem = map.WorkItem;
var parentInViews = viewMaps;
var workbenchItem = map.WorkbenchItem;
string LinkType = string.Empty;
WorkItemLinkCollection linkedWorkItems = workItem.WorkItemLinkHistory;
if (linkedWorkItems != null && linkedWorkItems.Count > 0)
LinkType = linkedWorkItems[0].LinkTypeEnd.LinkType.ReferenceName;
else if (workItem != null)
LinkType = workItem.Store.WorkItemLinkTypes.LinkTypeEnds["Parent"].LinkType.ReferenceName;
if (!string.IsNullOrEmpty(LinkType))
{
var viewMap = parentInViews.FirstOrDefault();
if (viewMap != null)
{
var linkName = LinkType;
var childType = viewMap.ChildType;
ILinkItem itm = Factory.BuildLinkItem(linkName, workbenchItem, workbenchItem);
return new {item = itm, filter=true};
}
}
return new {item = (ILinkItem)null, filter=false};
})
.Where(x=>x.filter)
.Select(x=>x.item)
.ToList();