21

有没有一种简单的方法可以逐步完成parallel.foreach?用断点调试它的最佳方法是什么?

4

7 回答 7

38

在调试期间,我经常将 my设置为设置为 1Parallel.ForEach运行MaxDegreeOfParallelism。这使得调试变得更加简单。

const bool forceNonParallel = true;
var options = new ParallelOptions { MaxDegreeOfParallelism = forceNonParallel ? 1 : -1 };
Parallel.ForEach(collection, options, item => 
{ //...

但是,这无助于调试与竞争条件或数据同步相关的问题,实际上通常会隐藏或消除代码中的实际问题。

使用 VS 2010 中的新工具(例如并行任务窗口)或使用调试多线程应用程序中列出的各种技术(例如切换线程、在单步执行时锁定线程等)通常可以更轻松地调试这些问题。

于 2012-06-19T20:41:33.280 回答
10

与此处的其他答案类似,我们在调试时将并行度设置为 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()

于 2014-03-27T10:42:00.520 回答
5

正如@PaulG 回答的那样,我认为最佳实践只是将MaxDegreeOfParallelism值设置为1. 然后通常Parallel也会像常规循环一样工作,如For, Foreach。这是在Parallel. 所以你不需要在常规循环和Parallel.

Parallel.For(0, itemsList.Count, new ParallelOptions { MaxDegreeOfParallelism = 1 }, i =>
{
    //your process goes here
}
于 2018-09-13T09:40:18.773 回答
5

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

在此处输入图像描述

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

在此处输入图像描述

于 2015-08-06T17:12:14.367 回答
0

暂时将其重写为非并行foreach,或在调试模式下运行时使用预处理器指令执行非并行代码。

于 2012-06-19T20:38:58.817 回答
0

我喜欢在断点上使用“When Hit”选项(右键单击断点,选择“When Hit...”。您可以向控制台打印一条消息,其中包括变量值、您所在的线程等.

于 2012-06-19T20:46:35.350 回答
0

OzCode 会给你很多帮助,它有一个特性,比如类固醇上的跟踪点,在调试并发\并行代码时非常有用 https://www.youtube.com/watch?v=_vuMi-3jGwY

于 2015-08-06T16:51:24.393 回答