Parallel.For和Break()的误解?我正在研究For循环中的并行中断。看完这篇文章,我还有一个疑问:我想要这样的代码:Parallel.For(0,10,(i,state)=>{Console.WriteLine(i);if(i==5)state.Break();}产生最多6个数字(0..6)。他不仅没有这样做,而且结果的长度也不同:023514860135420135642这很烦人。(地狱是Break(){after5}这里??)所以我在msdn上读到Break可用于与循环通信,在当前迭代之后不需要运行其他迭代。如果从for循环的第100次迭代调用Break从0到1000次迭代并行地,所有小于100的迭代仍应运行,但不需要从101到1000的迭代。问题#1:哪个迭代?整个迭代计数器?还是每个线程?我很确定它是每个帖子。请批准。问题#2:假设我们使用并行+范围分区(因为元素之间没有cpu成本变化),它在线程之间划分数据。所以如果我们有4个核心(并且它们之间有完美的划分):核心#1得到了0..250core#2got251..500core#3got501..750core#4got751..1000因此core#1的线程有时会遇到value=100并被中断。这将是他的第100次迭代。但是核心#4的线程获得了更多量子,现在他在900。他已经过了他的第100次迭代。他没有被小于100的索引阻塞!!-所以他会告诉他们所有的。我对吗?这就是为什么我在示例中获得超过5个元素的原因吗?问题#3:如果我真的break(i==5)怎么办?PS我的意思是,来吧!当我执行Break()时,我希望循环停止。正如我在常规For循环中所做的那样。最多生成6个数字(0..6)。问题是这最多不会产生6个数字。当您点击索引为5的循环时,它会发送一个“中断”请求。break()会导致循环不再处理任何>5的值,而是处理所有<5的值。但是,任何大于5的已启用值仍将被处理。由于各个索引并行运行,因此它们不再排序,因此您可以进行各种运行,其中某些值>5(如示例中的8)仍在执行。哪个迭代?整个迭代计数器?还是每个线程?我很确定这是每个帖子。请批准。这是传递给Parallel.For的索引。Break()不会阻止项目的处理,但保证最多处理100个项目,但超过100个的项目可能会或可能不会被处理。我对吗?这就是我在示例中获得超过5个元素的原因吗?是的。如果你像你展示的那样使用一个分区器,一旦你调用Break(),你打破的项目将不再被安排。但是,已经安排的项目(整个分区)将被完全处理。在您的示例中,这意味着您可能一直在处理所有1000个项目。我怎么才能真正打破(i==5)?你是-但当你并行运行时情况会发生变化。这里的实际目标是什么?如果只想处理前6个项目(0-5),则应在循环LINQ查询或类似查询之前限制项目。然后,您可以在Parallel.For或Parallel.ForEach中处理6个项目而无需Break(),而无需担心。我的意思是,来吧!当我执行Break()时,我希望循环停止。正如我在常规For循环中所做的那样。如果你想让事情尽快停止,你应该使用Stop()而不是Break()。这不会阻止已经运行的项目停止,但不会安排更多项目(包括索引较低或在枚举中比当前位置更早的项目)。如果从for循环的第100次迭代调用Break,则并行从0迭代到1000循环的第100次迭代不一定(实际上可能不会)具有索引99的那个。您的线程可以并且将会运行以不确定的顺序。遇到.Break()指令时不再启动循环迭代。确切发生这种情况的时间取决于特定运行的线程调度的详细信息。我强烈建议阅读并行编程模式(来自Microsoft的免费PDF)以了解进入TPL的设计决策和设计权衡。哪个迭代?整个迭代计数器?还是每个线程?关闭所有已安排(或尚未安排)的迭代。请记住,委托可能会乱序运行,不能保证迭代i==5将是第六次执行,除非在极少数情况下这不太可能。Q2:我说的对吗?不,调度不是那么简单。相反,所有任务都会排队,然后处理队列。但是每个线程都使用自己的队列,直到它们从其他线程窃取时队列为空。这使得无法预测哪个线程将处理哪个委托。如果委托非常简单,它可能会全部在原始调用线程上处理(没有其他线程有机会窃取工作)。Q3:当i(i==5)时,i真的断了怎么办?如果您想要线性(特定)处理,请不要同时使用两者。Break方法用于支持推测执行:尝试各种方法并在任何方法完成后立即停止。以上就是C#学习教程:Parallel.For和Break()的误解?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
