下記のプログラムのように、number個のタスクがあるとき、parallel個のCPUを使って並列計算したいのですが、以下のプログラムではうまくいきませんでした。
Invokeで実行した後に, actions[i]()が、一時変数のはずのiにアクセスしてしまい、IndexOutOfRangeExceptionが投げられてしまいます。
int parallel = 2;
int number = 100;
var data = new List<List<int>>();
Action[] actions = new Action[parallel];
for (int i = 0; i < parallel; i++) {
data.Add(new List<int>());
actions[i] = () => {
for (int b = i; b <= number; b += parallel)
data[i].Add(b*b);
};
}
Parallel.Invoke(actions);
原因はactions[i]の初期化にあるはずで、以下のコードの差し替えるとうまくいきます。
actions[0] = () => {
for (int b = 0; b <= number; b += parallel)
data[0].Add(b*b);
};
actions[1] = () => {
for (int b = 1; b <= number; b += parallel)
data[1].Add(b*b);
};
しかし、たとえばparallel=4などとするといちいちactionsを初期化するのは面倒ですし、処理内容を変えようとすると、4か所すべてを変更しなければならず、ミスを誘発します。
どうすればよいでしょうか。C#に詳しい方、教えてください。
お礼
なるほど、そんな解決策があったんですね!助かりました、ありがとうございました!