并行计算多个值。等待所有线程完成

时间:2016-08-03 03:09:29

标签: c# multithreading parallel-processing task-parallel-library

在C#中执行以下操作的惯用和最快方法是什么?假设我有一个有三个值的类(它总是三个值,所以预先分配3个任务就可以了):

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
}

2 个答案:

答案 0 :(得分:3)

您可以使用Task.WaitAll方法等待所有任务完成。下面提供了一个简单的解决方案。

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;
}

等待Task.WhenAll也可用于等待所有任务完成。

答案 1 :(得分:2)

如果ComputeAComputeBComputeC不是异步的(并且它们不在您的代码中,因为它们会返回double而不是Task<double> ),然后你可以使用Parallel.Invoke

public AggregateValues Compute()
{
    AggregateValues av = new AggregateValues();
    Parallel.Invoke(
        () => { av.A = ComputeA(); },
        () => { av.B = ComputeB(); },
        () => { av.C = ComputeC(); });
    return av;
}

在您的场景中,Parallel.Invoke稍好于Task.WaitAllTask.WhenAll,因为Parallel.Invoke可以重用其中一个任务的调用线程。