I need to traverse a tree quickly, and I would like to do it in parallel. I\'d rather use the parallel extensions than manually spin up a bunch of threads.
My current co
The most direct way would be to create a Task
for each child node and then wait for all of them:
public void Traverse(Node root)
{
if (node.Property == someValue)
DoSomething(node);
var tasks = new List();
foreach (var node in node.Children)
{
// tmp is necessary because of the way closures close over loop variables
var tmp = node;
tasks.Add(Task.Factory.StartNew(() => Traverse(tmp)));
}
Task.WaitAll(tasks.ToArray());
}
Task
is fairly light-weight, so creating lots of them works reasonably well. But they do have some overhead, so doing something more complicated like having a few tasks that share a queue is probably going to be faster. If that's the way you're going to go, don't forget that empty queue doesn't mean all work is done. Classes from the System.Collections.Concurrent
namespace are going to come handy if you went this way.
EDIT: Because of the shape of the tree (the root has about 500 children), processing just the first level in parallel should give good performance:
public void Traverse(Node root, bool parallel = true)
{
if (node.Property == someValue)
DoSomething(node);
if (parallel)
{
Parallel.ForEach(node.Children, node =>
{
Traverse(node, false);
});
}
else
{
foreach (var node in node.Children)
{
Traverse(node, false);
}
}
}