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&lt;T&gt;.AsParallel() 不太一样 - https://***.com/questions/3789998/parallel-foreach-vs-foreachienumerablet-asparallel【参考方案3】:

您实际上可以使用 Visual Studio 获得类似的结果,只需冻结除一个之外的所有线程,在“线程”窗口中选择除一个之外的所有线程并右键单击 -> 像这样冻结:

此外,如果您想重现竞态条件并在断点处停止会破坏它,您可以随时添加跟踪点 - 使用 Visual Studio 或帮助它的插件,例如 Oz Code

【讨论】:

【参考方案4】:

正如@PaulG 回答的那样,我认为最佳实践只是将MaxDegreeOfParallelism 值设置为1。然后通常Parallel 也将类似于ForForeach 等常规循环。这是在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?

强制终止由 Parallel.ForEach 生成的线程 [重复]

C# - 用于服务调用的 Parallel.Foreach()

Parallel.ForEach 会按照 MaxDegreeOfParallelism=1 的顺序进行处理吗?