Ste*_*lan 8 c# parallel-processing performance foreach
我有一个方法:
IList<string> pages = new List<string>();
foreach (var node in nodes)
{
try
{
string temp = DoSomeComplicatedModificationOnNode(node);
if (temp.ToLower().Contains(path))
{
pages.Add(node.Title);
}
}
catch (Exception)
{
continue;
}
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,DoSomeComplicatedModificationOnNode()会给出异常,这就是使用try {} catch块的原因 - 我可以跳过给出异常的项目.节点数包含数千个项目,项目具有多个属性.如何优化此循环?我在考虑Parallel.Foreach,但是下面的代码给出了一个错误"Missing current principal":
IList<string> pages = new List<string>();
Parallel.ForEach(pageNodes, node =>
{
try
{
string temp = DoSomeComplicatedModificationOnNode(node);
if (temp.ToLower().Contains(path))
{
pages.Add(node.Title);
}
}
catch (Exception)
{
}
});
Run Code Online (Sandbox Code Playgroud)
小智 9
在C#中,通用列表不是线程安全的,因此您无法在并行循环中添加项.
我建议使用另一个类,如ConcurrentBag,ConcurrentStack或ConcurrentQueue.
var pages = new ConcurrentBag<string>();
Parallel.ForEach(pageNodes, node =>
{
try
{
string temp = DoSomeComplicatedModificationOnNode(node);
if (temp.ToLower().Contains(path))
pages.Add(node.Title);
}
catch (Exception)
{
throw;
}
});
Run Code Online (Sandbox Code Playgroud)
请记住,并行任务是无序的,如果您需要订单,则必须在并行中使用索引.列表只是thead-save用于阅读.
System.Threading.Tasks.Parallel.For(0, pageNodes.Count, index =>
{
string node = pageNodes[index];
try
{
string temp = DoSomeComplicatedModificationOnNode(node);
if (temp.ToLower().Contains(path))
pages.Add(MyPage(index, node.Title));
}
catch (Exception)
{
throw;
}
});
Run Code Online (Sandbox Code Playgroud)
List<T> 在大多数情况下不是线程安全的。看一下线程安全集合,例如 ConcurrentBag<T>。