C# 从本地init lambda终止Parallel.ForEach循环的最佳方法是什么?
在我的C# 从本地init lambda终止Parallel.ForEach循环的最佳方法是什么?,c#,parallel.foreach,C#,Parallel.foreach,在我的Parallel.ForEach循环中,我需要在“localinit”lambda中初始化一些对象。 如果其中一个对象未能初始化,我想终止整个并行循环。 最好的方法是什么 Parallel.ForEach(collection, () => //local init { var localObjects= CreateObjects(); foreach (var obj in localObjects) if (!obj.Ini
Parallel.ForEach
循环中,我需要在“localinit”lambda中初始化一些对象。
如果其中一个对象未能初始化,我想终止整个并行循环。
最好的方法是什么
Parallel.ForEach(collection,
() => //local init
{
var localObjects= CreateObjects();
foreach (var obj in localObjects)
if (!obj.Initialize())
// want to terminate the entire parallel loop here!!
return localObjects;
}
(element, loopState, localObjects) => // loop body
{
// some code here
},
localObjects => // local finally
{
foreach (var obj in localObjects)
obj.Terminate();
});
最好的方法是检查您试图初始化的对象是否为null
,如果是,break()
我希望这有帮助
编辑。根据一些注释,stop()
在这种情况下可能是更好的选择。最好的方法是检查您尝试初始化的对象是否为null
,如果是,break()
我希望这有帮助
编辑。在一些注释之后,
stop()
在这种情况下可能是更好的选择。可能是这样的
Parallel.ForEach(collection,
() => //local init
{
var localObjects= CreateObjects();
foreach (var obj in localObjects)
if (!obj.Initialize())
return null; // returning null as a "flag" for the loop
// body block to use
return localObjects;
},
(element, loopState, localObjects) => // loop body
{
if (state.IsStopped || localObjects == null)
{
// will signal to stop at earliest convenience
loopState.Stop();
// will make sure nothing is done this iteration
return null;
}
// some code here
},
localObjects => // local finally
{
foreach (var obj in localObjects)
obj.Terminate();
});
请注意,这将意味着finally块中的localObjects也将为null,并且没有任何内容将是
Terminate()
d.可能是这样的
Parallel.ForEach(collection,
() => //local init
{
var localObjects= CreateObjects();
foreach (var obj in localObjects)
if (!obj.Initialize())
return null; // returning null as a "flag" for the loop
// body block to use
return localObjects;
},
(element, loopState, localObjects) => // loop body
{
if (state.IsStopped || localObjects == null)
{
// will signal to stop at earliest convenience
loopState.Stop();
// will make sure nothing is done this iteration
return null;
}
// some code here
},
localObjects => // local finally
{
foreach (var obj in localObjects)
obj.Terminate();
});
请注意,这将意味着finally块中的localObjects也将为null,并且没有任何东西将是
Terminate()
d.,这将起作用,但我希望更干净一些。我考虑从那里抛出一个异常,这应该可以实现我想要的技巧think@dmg请不要使用异常来控制应用程序逻辑。它们是为你意想不到的特殊事件准备的。根据你所写的代码,你似乎期望事情不会初始化。当然,在这个代码中,初始化可能会很容易失败。如果你的代码被初始化,那一定是一个中断。或者更丑陋的事件,一个goto
。等等,我想FORTRANs就在门口……我们不能简单地把从Parallel.ForEach()中分离出来。这是因为就语言而言,它不是一个循环。这会起作用,但我想要更干净的东西。我考虑从那里抛出一个异常,这应该可以实现我想要的技巧think@dmg请不要使用异常来控制应用程序逻辑。它们是为你意想不到的特殊事件准备的。根据你所写的代码,你似乎期望事情不会初始化。当然,在这个代码中,初始化可能会很容易失败。如果你的代码被初始化,那一定是一个中断。或者更丑陋的事件,一个goto
。等等,我想FORTRANs就在门口……我们不能简单地把从Parallel.ForEach()中分离出来。这是因为就语言而言,它不是一个循环。我们可以肯定的是,在这里-您知道,集合
集合中的每个元素都会调用localnit和localFinally一次,对吧?我们可以肯定,这里-您知道,集合
集合中的每个元素都将调用一次localnit和localFinally,对吧?Break()
在迭代之后停止,这不是您想要的,您想要停止一切。老实说,我是在两者之间做出选择的。然而,我看不出我自己的测试与这段代码有什么不同。它仍然会完成已经产生的迭代。考虑到它需要与IsStopped
相结合,我把它省略了。修改。=)如果只有一些本地对象未能初始化,则会产生影响。(例如,如果项目75–100的本地对象没有初始化,使用Break()
意味着项目75–100不会被处理,但是项目0–74会被处理。)这正是Break()
的目的,请看一下中的备注。@svick我指的是编辑,而不是您的解释。我完全理解,非常感谢你说得清楚Break()
在迭代之后停止,这不是您想要的,您想要停止一切。老实说,我是在两者之间做出选择的。然而,我看不出我自己的测试与这段代码有什么不同。它仍然会完成已经产生的迭代。考虑到它需要与IsStopped
相结合,我把它省略了。修改。=)如果只有一些本地对象未能初始化,则会产生影响。(例如,如果项目75–100的本地对象没有初始化,使用Break()
意味着项目75–100不会被处理,但是项目0–74会被处理。)这正是Break()
的目的,请看一下中的备注。@svick我指的是编辑,而不是您的解释。我完全理解,非常感谢你说得清楚