'Parallel.ForEach Debug or Step Through

Is there an easy way to step through a parallel.foreach? What is the best way to debug this with a break point?



Solution 1:[1]

You can actually get similar results with Visual Studio just by freezing all the threads except one, select all threads but one in the Threads windows and right click -> Freeze like this:

enter image description here

Also, if you want to reproduce a race condition and stopping on breakpoints breaks it, you can always add tracepoints - either with visual studio or with plugins that help with it, such as Oz Code

enter image description here

Solution 2:[2]

During debug, I'll often setup my Parallel.ForEach to run with MaxDegreeOfParallelism set to 1. This makes it far simpler to debug.

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

However, this will not help with debugging issues relating to race conditions or data synchronization, and will in fact often hide or eliminate real problems in your code.

Those issues can often be debugged much more easily by using the new tools in VS 2010, such as the Parallel Tasks window, or by using the various techniques listed in Debugging Multithreaded Applications, such as switching threads, locking threads while stepping, etc.

Solution 3:[3]

Similar to other answers here, we set degree of parallelism to 1 when debugging, but we do this with an extension method, like:

public static ParallelQuery<TSource> AsDebugFriendlyParallel<TSource>(this IEnumerable<TSource> source)
{
    var pQuery = source.AsParallel();
    #if DEBUG
    pQuery = pQuery.WithDegreeOfParallelism(1);
    #endif

    return pQuery;
}

Then, instead of using .AsParallel() we use .AsDebugFriendlyParallel()

Solution 4:[4]

As @PaulG answered i think best practice is just set MaxDegreeOfParallelism value to 1. Then normally Parallel also will work similar to regular loop like For, Foreach. This is the faster way to debug on Parallel. So you don't need to switch code between regular loop and Parallel.

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

Solution 5:[5]

Temporarily rewrite it as a non-parallel foreach, or use preprocessor directives to execute non-parallel code when running in debug mode.

Solution 6:[6]

I like to use the "When Hit" option on a breakpoint (right-click the breakpoint, select "When Hit...". You can print a message to the console that includes values of variables, the thread you are on, etc.

Solution 7:[7]

OzCode will help you a lot, it has a feature like tracepoints on steroids that is super useful when debuging concurrent\parallel code https://www.youtube.com/watch?v=_vuMi-3jGwY

Solution 8:[8]

This is the strategy I use which makes every Loop go sequential when in debug mode

 var parOpts = new ParallelOptions { MaxDegreeOfParallelism = -1 }; //No limit to parallel degree

#if DEBUG
            parOpts.MaxDegreeOfParallelism = 1; //Set parallel to 1
#endif

        Parallel.ForEach(links, node =>
        {
            string url = node.Attributes["href"].Value;
            Link link = ParseLink(url);
            link.LinkText = node.InnerText;

            if (link.Domain == RootLink.Domain)
            {
                if (link.Page == RootLink.Page)
                    link.Type = LinkType.Section;
                else
                    link.Type = LinkType.Internal;
            }
            else
                link.Type = LinkType.External;

            linksList.Add(link);
        });

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stas Sh
Solution 2 Reed Copsey
Solution 3 PaulG
Solution 4 Liakat Hossain
Solution 5 Bob Black
Solution 6 Kevin Aenmey
Solution 7 Tamir Dresher
Solution 8 Cyril Gupta