C#parallelize loop

时间:2017-10-23 15:33:51

标签: c# parallel-processing

我有以下c#代码:

        int[] ns = new int[4] { 100, 500, 1000, 5000 };
        int[] ks = new int[5] { 5, 10, 15, 80, 160 };
        int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        for(int n = 0; n<ns.Length; n++)
        {
            for(int k = 0; k < ks.Length; k++)
            {
                for (int r = 0; r < rs.Length; r++)
                {
                    RunProg(ns[n], ks[k], rs[r]);
                }
            }
        }

其中RunProg需要相当长的时间。我想并行化这段代码。在C#中最直接的并行化方法是什么?

我还没有尝试过任何方法。我试图在不同的functionalities available in C#

之间做出决定

3 个答案:

答案 0 :(得分:2)

Parallel.For方法:

int[] ns = new int[4] { 100, 500, 1000, 5000 };
int[] ks = new int[5] { 5, 10, 15, 80, 160 };
int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Parallel.For(0, ns.Length, n =>
{
    Parallel.For(0, ks.Length, k =>
    {
        Parallel.For(0, rs.Length, r =>
        {
            RunProg(ns[n], ks[k], rs[r]);
        });
    });
});

如果调用RunProg方法的顺序不重要,并且方法本身是线程安全的,那么这应该可行。

答案 1 :(得分:2)

一种简单的并行化方法是生成一个表示所有输入组合的序列,然后将此序列转换为表示结果的一系列线程池任务。可以简单地将此最终序列传递给Task.WhenAll以等待所有任务的完成。

class Program
{
    static void Main(string[] args)
    {
        int[] ns = new int[4] { 100, 500, 1000, 5000 };
        int[] ks = new int[5] { 5, 10, 15, 80, 160 };
        int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        var inputs = ns
            .SelectMany(n => ks.Select(k => new { n, k }))
            .SelectMany(x => rs.Select(r => new { x.n, x.k, r }));

        var tasks = inputs.Select(x => Task.Run(() => RunProg(x.n, x.k, x.r)));
        var results = Task.WhenAll(tasks).Result;
    }

    static int RunProg(int n, int k, int r)
    {
        Thread.Sleep(1000);
        return n + k + r;
    }
}

您还可以在Parallel.ForEach集合上inputs,如其他答案中所述。

Parallel.ForEach(inputs, x => RunProg(x.n, x.k, x.r));

答案 2 :(得分:0)

使用try { WriteLog("Installing...") $installresult = (Start-Process msiexec.exe -ArgumentList "/i $PSScriptRoot + \test\InstallPrism6.msi /qn /norestart" -Wait -PassThru).ExitCode WriteLog("Installation finished with return code: $installresult") } catch { WriteLog($_.Exception.Message) } 进行循环:https://msdn.microsoft.com/de-de/library/dd460713(v=vs.110).aspx

如果迭代不相互依赖,则此方法有效。