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我指的是编辑,而不是您的解释。我完全理解,非常感谢你说得清楚