Reputation: 7746
What is the idiomatic and fastest way to do the following in C#? Say I have a class that has three values (it is always three values so pre allocating 3 tasks is ok):
public class AggregateValues
{
public double A { get; set;}
public double B { get; set;}
public double C { get; set;}
}
public AggregateValues Compute()
{
//How do I parallize these?
AggregateValues av = new AggregateValues();
av.A = ComputeA();
av.B = ComputeB();
av.C = ComputeC();
//Wait for ComputeA, ComputeB, ComputeC to be done
return av;
}
public double ComputeA()
{
// Complicated code
}
public double ComputeB()
{
// Complicated code
}
public double ComputeC()
{
// Complicated code
}
Upvotes: 1
Views: 205
Reputation: 55409
If ComputeA
, ComputeB
, and ComputeC
aren't asynchronous (and they aren't in your code because they return double
instead of Task<double>
), then you can use Parallel.Invoke:
public AggregateValues Compute()
{
AggregateValues av = new AggregateValues();
Parallel.Invoke(
() => { av.A = ComputeA(); },
() => { av.B = ComputeB(); },
() => { av.C = ComputeC(); });
return av;
}
In your scenario, Parallel.Invoke is slightly better than Task.WaitAll or Task.WhenAll because Parallel.Invoke can reuse the calling thread for one of the tasks.
Upvotes: 2
Reputation: 488
You could use Task.WaitAll method to wait for all tasks to complete. A simple solution to your case is provided below.
public AggregateValues Compute()
{
//How do I parallize these?
AggregateValues av = new AggregateValues();
Task taskA = Task.Factory.StartNew(() => av.A = ComputeA());
Task taskB = Task.Factory.StartNew(() => av.B = ComputeB());
Task taskC = Task.Factory.StartNew(() => av.C = ComputeC());
//Wait for ComputeA, ComputeB, ComputeC to be done
Task.WaitAll(taskA, taskB, taskC);
return av;
}
await on Task.WhenAll can also be used to wait for all tasks to be completed.
Upvotes: 3