我在DTable中实现Parallel.ForEach时遇到问题。以下是我正在实施的示例代码:
Parallel.ForEach(dTable4.AsEnumerable(), row4 =>
{
string getCondition = row4[1].ToString();
getCondition = EvaluateCondExpression(getCondition); //Evaluates CM for value (CM1==2 && CM2<5);
Expression e = new Expression(getCondition); //getCondition = (2==2 && 2<5)
var evalutateCondition = e.Evaluate();
if (Convert.ToBoolean(evalutateCondition))
{
//Write string to TextBox
}
}
当我运行它时,线程没有被有效管理,并且它比foreach循环花费太多时间。 在从GUI组合框和numericUpDown检查用户提供的参数后,EvaluateCondExpression函数返回值
private string EvaluateCondExpression(string getCondition)
{
string[] splitgetCondition1 = SeprateCharacter(getCondition);
foreach (string oneCondition in splitgetCondition1)
{
string conditionValue = oneCondition;
if (oneCondition.Contains("CM"))
{
conditionValue = RemoveMultipleChar(conditionValue.Replace('!', ' ').Trim());
string getInputNumber = getTableOneInputNo(conditionValue, dTable1);
string tableOneValue = checkComboxValue(m_comboBox, getInputNumber);
getCondition = getCondition.Replace(conditionValue, tableOneValue);
}
}
return getCondition;
}
串行ForEach计算花费了太多时间,所以我想应用Parallel.ForEach迭代,但遗憾的是它无法正常工作。任何人都可以建议我如何最大限度地提高性能以及我在Parallel.ForEach中做错了什么。
答案 0 :(得分:3)
通过使用传统的foreach,在Task中包装每次迭代,您可能会看到性能提升。将每次迭代的任务添加到集合中,然后在foreach调用之外调用Task.WhenAll(tasks);如果有什么它可以让你有能力等待昂贵的并行过程。
您可以将Parallel.ForEach的内容转换为Select Linq查询,该查询将每次迭代转换为Task。生成的任务集合可以提供给Task.WhenAll方法以等待
这可能无法解决您所看到的性能瓶颈,但这至少会让您等待并行进程并释放UI线程。
答案 1 :(得分:2)
运行循环的一次迭代需要多长时间?你运行了多少次迭代?通常,Parallel.Foreach()非常适合运行循环,其中每次迭代可能需要相当长的时间。如果你有相当快速操作的许多迭代,你将花费大量额外的开销来生成和管理线程,这可能是你所看到的。有关此类场景的更多信息,请参阅此MSDN文章:
https://msdn.microsoft.com/en-us/library/dd560853(v=vs.110).aspx
<强>更新强>
Here是Parallel.Foreach()和await Task.WhenAll()的良好比较。
答案 2 :(得分:2)
使用Parallel.ForEach
时,您可以对代码进行以下修改,尤其是对于长时间运行的任务
Parallel.ForEach( dTable4.AsEnumerable(), new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount}, row4 = >
这将确保Parallel.ForEach不会启动datatable
中每个数据点的线程,它只会动态地根据环境处理器/核心的数量生成线程,从而减少争用和线程上下文切换。但理想情况下,如上所述,您可以为长时间运行的任务规划异步模式。
我看到你正在更新Parallel循环中的UI控件,为此你无论如何都需要UI线程上下文,否则它将是一个异常。无论如何,Async在UI线程上下文中运行