debugging Parallel.Foreach

nkat

Member
Joined
Jun 29, 2022
Messages
18
Programming Experience
1-3
Good day, everyone!
Here's this marvelous piece of code that uses Parallel.ForEach to build an Active Directory OU tree.

C#:
using System.DirectoryServices;

using System.Threading.Tasks;



public class ADTree

{

    DirectoryEntry rootOU = null;

    string rootDN = string.Empty;

    List<ADTree> childOUs = new List<ADTree>();



    public DirectoryEntry RootOU

    {

        get { return rootOU; }

        set { rootOU = value; }

    }



    public string RootDN

    {

        get { return rootDN; }

        set { rootDN = value; }

    }



    public List<ADTree> ChildOUs

    {

        get { return childOUs; }

        set { childOUs = value; }

    }



    public ADTree(string dn)

    {

        RootOU = new DirectoryEntry(dn);

        RootDN = dn;

        BuildADTree().Wait();

    }



    public ADTree(DirectoryEntry root)

    {

        RootOU = root;

        RootDN = root.Path;

        BuildADTree().Wait();

    }



    private Task BuildADTree()

    {

        return Task.Factory.StartNew(() =>

        {

            object locker = new object();

            Parallel.ForEach(RootOU.Children.Cast<DirectoryEntry>().AsEnumerable(), child =>

            {

                if (child.SchemaClassname.Equals("organizationalUnit"))

                {

                    ADTree ChildTree = new ADTree(child);

                    lock (locker)

                    {

                        ChildOUs.Add(ChildTree);

                    }

                }

            });

        });

    }

}

My aim is to figure out how it works, so I have rewritten the code without Parallel.ForEach and it works just fine, the idea is a simple recursion, alright.
Still, even though, I understand how the tree is built in no parallel fashion, I don't get how it is done in parallel. If I debug it, then the line #93
C#:
return Task.Factory.StartNew(() => )
is just a line that does all the parallel magic and debugger cannot go in.
Would someone shed light on what's going on in there or recommend a way to "debug Tasks"
 
Recall what Task.Factory.StartNew() does: It creates a new Task object and enqueues that task into the system thread pool. Eventually a thread pool thread will free up and the task will be assigned to that thread pool until it yields (due to an await or finishes executing the task). The debugger can't step into the thread pool scheduler (easily) because it doesn't know when a thread will free up to start running the task.

Your easiest approach is to just set a breakpoint on line 91. When a thread eventually starts running the task, the debugger will be alert when the CPU tries to execute that line.

Anyway, I have two recommendations:
1) Read the documentation. You will gain a lot more insight that way rather than by trying to step through code and set breakpoints:

2) Get a copy of Stephen Cleary's "Concurrency in C# Cookbook". Despite the title, he doesn't just dump "recipes" on you. He actually goes into a very deep explanation of how things work before he introduces "recipes" that take advantage of how things work. He covers all of TPL, which includes Parallel.ForEach().
 
Back
Top Bottom