Parallel.ForEach 调试或单步执行
Posted
技术标签:
【中文标题】Parallel.ForEach 调试或单步执行【英文标题】:Parallel.ForEach Debug or Step Through 【发布时间】:2012-06-21 23:11:22 【问题描述】:有没有一种简单的方法来逐步完成parallel.foreach?使用断点进行调试的最佳方法是什么?
【问题讨论】:
如果您不想调试并行性,而只想检查循环内发生的情况,请将其复制到串行 foreach 并逐步执行(注释掉并行以进行生产)跨度> @Dimitri Safer/simpler 让Parallel.ForEach
按顺序运行以进行调试。
@Reed - 是的,这就是为什么我赞成你的回答。以前没想过
【参考方案1】:
在调试期间,我经常将Parallel.ForEach
设置为在MaxDegreeOfParallelism
设置为1 的情况下运行。这使得调试变得更加简单。
const bool forceNonParallel = true;
var options = new ParallelOptions MaxDegreeOfParallelism = forceNonParallel ? 1 : -1 ;
Parallel.ForEach(collection, options, item =>
//...
但是,这无助于调试与竞争条件或数据同步相关的问题,实际上通常会隐藏或消除代码中的实际问题。
这些问题通常可以通过使用 VS 2010 中的新工具(例如 Parallel Tasks window)或使用 Debugging Multithreaded Applications 中列出的各种技术(例如 switching threads,在步进时锁定线程)更容易地调试等。
【讨论】:
你知道 "-1" 的任何文档吗? msdn文章说如果设置为0或低于-1的任何值都会抛出错误,但没有解释-1。 @granadaCoder 见msdn.microsoft.com/en-us/library/… "如果为-1,则对并发运行的操作数没有限制。"【参考方案2】:与此处的其他答案类似,我们在调试时将并行度设置为 1,但我们使用扩展方法来执行此操作,例如:
public static ParallelQuery<TSource> AsDebugFriendlyParallel<TSource>(this IEnumerable<TSource> source)
var pQuery = source.AsParallel();
#if DEBUG
pQuery = pQuery.WithDegreeOfParallelism(1);
#endif
return pQuery;
然后,我们不使用.AsParallel()
,而是使用.AsDebugFriendlyParallel()
【讨论】:
请注意Parallel.ForEach()
和 IEnumerable<T>.AsParallel()
不太一样 - https://***.com/questions/3789998/parallel-foreach-vs-foreachienumerablet-asparallel【参考方案3】:
您实际上可以使用 Visual Studio 获得类似的结果,只需冻结除一个之外的所有线程,在“线程”窗口中选择除一个之外的所有线程并右键单击 -> 像这样冻结:
此外,如果您想重现竞态条件并在断点处停止会破坏它,您可以随时添加跟踪点 - 使用 Visual Studio 或帮助它的插件,例如 Oz Code
【讨论】:
【参考方案4】:正如@PaulG 回答的那样,我认为最佳实践只是将MaxDegreeOfParallelism
值设置为1
。然后通常Parallel
也将类似于For
、Foreach
等常规循环。这是在Parallel
上进行调试的更快方法。所以你不需要在常规循环和Parallel
之间切换代码。
Parallel.For(0, itemsList.Count, new ParallelOptions MaxDegreeOfParallelism = 1 , i =>
//your process goes here
【讨论】:
【参考方案5】:暂时将其重写为非并行的foreach,或者在调试模式下运行时使用预处理器指令执行非并行代码。
【讨论】:
【参考方案6】:我喜欢在断点上使用“When Hit”选项(右键单击断点,选择“When Hit...”。您可以向控制台打印一条消息,其中包含变量的值,您所在的线程等。
【讨论】:
【参考方案7】:OzCode 可以帮到你很多,它有一个特性,比如类固醇上的跟踪点,在调试并发\并行代码时非常有用 https://www.youtube.com/watch?v=_vuMi-3jGwY
【讨论】:
以上是关于Parallel.ForEach 调试或单步执行的主要内容,如果未能解决你的问题,请参考以下文章
为啥要先执行 Return 语句而不是 Parallel。 ForEach [重复]
基于需要在执行时间内接收更多项目的列表执行 Parallel.ForEach
强制终止由 Parallel.ForEach 生成的线程 [重复]