Reputation: 1421
I have a structure like this.
Parent-----Children1
|
-------Children2
|
-------Children2.1
|
--------Children2.2
How can I loop into this tree and execute Parent in new Task, then when is finished Children1 and Children2 parallel, then when is finished Children2.1 and Children2.2 also parallel? So the order of executing is like in graph.
Upvotes: 1
Views: 1526
Reputation: 1386
Try TreeifyTask
GithubLinkHere
You can create root and sub tasks those can be executed in an order sequentially or in parallel. The handle is from the root node.
Usage: Create root task and child tasks
ITaskNode rootTask = new TaskNode("root");
ITaskNode childTask_1 = new TaskNode("Task-1");
ITaskNode childTask_2 = new TaskNode("Task-2");
rootTask.AddChild(childTask_1);
rootTask.AddChild(childTask_2);
Usage: Set actions to child tasks
childTask_1.SetAction(async (reporter, cancellationToken) => {
// Simple delay function.
reporter.ReportProgress(TaskStatus.InProgress, 10, "Started...");
await Task.Delay(1000);
reporter.ReportProgress(TaskStatus.InProgress, 100, "Finished...");
});
childTask_2.SetAction(async (reporter, cancellationToken) => {
// Simple delay function.
reporter.ReportProgress(TaskStatus.InProgress, 5, "Started...");
await Task.Delay(2500);
reporter.ReportProgress(TaskStatus.InProgress, 100, "Finished...");
});
Usage: Subscribe to Root node
// Before starting the execution, you need to subscribe for progress report.
rootTask.Reporting += (object sender, ProgressReportingEventArgs eventArgs) => {
eventArgs.ProgressValue; // -> this will represent the overall progress
};
Usage: Start execution
// Create and pass the cancellation token
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
// Start the execution concurrently
rootTask.ExecuteConcurrently(cancellationToken: token, throwOnError: true);
// OR
// Start the execution in series
rootTask.ExecuteInSeries(cancellationToken: token, throwOnError: true);
Error handling is easy as Execute*
methods throw exception with entire tree structure. Here the ID
plays a role and it helps to to debug quickly.
Upvotes: 0
Reputation: 1511
If you are looking for a bit more robust code, take a look at the following project of mine on github:
It contains a simple .Net tool for discovering a huge tree structure efficiently (without consuming much resources) and still parallel, without a bottleneck. It was designed to deal with async calls in mind.
An example for discovering a directory structure in the file system:
await TreeWalker.WalkAsync(root, new TreeWalkerOptions
{
MaxDegreeOfParallelism = 5,
ProcessElementAsync = async (element) =>
{
// this is the action that is executed on every element
var el = element as FileSystemElement;
var path = el.Path;
var isDirectory = el.IsDirectory;
await DoStuffAsync(el);
}
});
This single method call makes the plugin discover the full tree structure and lets you execute an action on every element.
The FileSystemElement class above is a built-in sample implementation of the ITreeElement interface, you can create your own class for your structure (or implement the very simple interface in your existing class).
Upvotes: 0
Reputation: 22565
use Parallel.Foreach for running task on all childs, and then in the end call all childs subchild:
void run()
{
do action on parent;
DoTasks(parent);
}
void DoTasks(Node node)
{
if (node.Childs == null) return;
Parallel.Foreach(node.Childs, child => {do action})
foreach(var child in node.Childs)
{
DoTasks(child);
}
}
parallel.foreach waits untill all tasks finished.
Upvotes: 2