Parallel.ForEach Debug或Step Through

时间:2012-06-19 20:35:24

标签: c# debugging parallel.foreach

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

7 个答案:

答案 0 :(得分:30)

在调试期间,我经常将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 :(得分:9)

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

答案 2 :(得分:4)

实际上你可以通过冻结除了一个之外的所有线程来获得与Visual Studio类似的结果,在Threads窗口中选择所有线程,然后右键单击 - &gt;像这样冻结:

enter image description here

此外,如果你想重现一个竞争条件并且在断点处停止会破坏它,你可以随时添加跟踪点 - 使用visual studio或使用有助于它的插件,例如Oz代码

enter image description here

答案 3 :(得分:2)

正如@PaulG回答的那样,我认为最佳实践只是将MaxDegreeOfParallelism的值设置为1。然后,通常Parallel也将类似于ForForeach之类的常规循环。这是在Parallel上调试的更快方法。因此,您无需在常规循环和Parallel之间切换代码。

Parallel.For(0, itemsList.Count, new ParallelOptions { MaxDegreeOfParallelism = 1 }, i =>
{
    //your process goes here
}

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

OzCode会对你有很大的帮助,它有像类固醇上的跟踪点这样的功能,在对并发\并行代码进行调试时非常有用 https://www.youtube.com/watch?v=_vuMi-3jGwY