是否有一种简单的方法可以逐步完成parallel.foreach?使用断点调试此方法的最佳方法是什么?
答案 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;像这样冻结:
此外,如果你想重现一个竞争条件并且在断点处停止会破坏它,你可以随时添加跟踪点 - 使用visual studio或使用有助于它的插件,例如Oz代码
答案 3 :(得分:2)
正如@PaulG回答的那样,我认为最佳实践只是将MaxDegreeOfParallelism
的值设置为1
。然后,通常Parallel
也将类似于For
,Foreach
之类的常规循环。这是在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