Reputation: 326
Say I have two classes A
and B
that derive from an interface (say IAorB
). A
contains a list of IAorB
objects:
public interface IAorB { ... }
public class A
{
...
public List<IAorB> Children { get; set; }
...
}
public class B { ... }
If I wanted apply an operation to an IAorB
object and all its children (if any) asynchronously, would the following approach be recommended? If not, is there a better way?
public Task SomeOperation(IAorB object) { ... } //May take some time
public Task<List<Task>> OperateRecursively(A root)
{
List<Task> tasks = new List<Task>();
foreach (IAorB child in root.Children)
{
if (child.GetType() == typeof(B))
{
tasks.Add(SomeOperation(child));
}
else
{
tasks.Add(OperateRecursively(child as A));
}
}
tasks.Add(SomeOperation(root));
return tasks;
}
Optimally, OperateRecursively
would return a List
of Tasks
that I can use Task.WaitAll()
on. But this approach returns nested List<Task>
s, which probably isn't optimal.
Upvotes: 1
Views: 620
Reputation: 32068
I think you just got a little confused with the syntax. This should be what you are looking for:
// fix method signature, this doesn't run asynchronous code so it needs not be a Task
public IEnumerable<Task> OperateRecursively(A root)
{
List<Task> tasks = new List<Task>();
foreach (IAorB child in root.Children)
{
if (child is B)
{
tasks.Add(SomeOperation(child));
}
else
{
// 1. change to AddRange since you are adding multiple elements, not one
// 2. fix name for actual recursion
// 3. cast child to A since otherwise it wouldn't compile
tasks.AddRange(OperateRecursivelyA(child as A));
}
}
tasks.Add(SomeOperation(root));
return tasks;
}
Which you would then simply use as
await Task.WhenAll(OperateRecursivelyA(someRoot));
Upvotes: 3