我有以下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#
之间做出决定答案 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
如果迭代不相互依赖,则此方法有效。