2017-04-21 5 views
0

私は関数を呼び出すが、それらを条件付きで呼び出そうとするシナリオがあります。したがって、以下のコードでは、関数2と3のみが呼び出されます。しかし、アクション部分は値を返しませんが、私の場合は戻り値を保存します。条件付きでの並列呼び出し

List<int> list = new List<int> {2,3}; 
Dictionary<int, Action> actions = new Dictionary<int, Action>() 
{ 
    {1, Function1}, 
    {2, Function2}, 
    {3, Function3} 
}; 

Parallel.Invoke((from action in list select actions[action]).ToArray()); 

最初はコードの下にありましたが、これはすべての機能を呼び出します。何かご意見は?あなたが実行から結果が必要な場合は

Parallel.Invoke(
() => return1=function1, 
() => return2=function2, 
() => return3=function3 
); 
+0

呼び出されていない関数に対して返されるものは何ですか? – svick

答えて

0

は、ParallelActionはあなたの関数の結果を取得することができなくなりますが、私たちはTaskFunc<T>を使用している場合、我々はそれらを並列に実行した後に戻って結果を得ることができます。

Parallelの代わりにTaskを使用して、機能を同時に実行し、結果を保存することができます。関数1,2,3の戻り値の型としてintと仮定しました。必要に応じて変更することができます。

List<int> list = new List<int> { 2, 3 }; 
Dictionary<int, Func<int>> actions = new Dictionary<int, Func<int>>() 
{ 
    {1, Function1}, 
    {2, Function2}, 
    {3, Function3} 
}; 


List<Task<int>> taskList = (from a in list select Task.Run(actions[a])).ToList(); 

// Allow all processing to finish before accessing results 
Task.WaitAll(taskList.ToArray()); 
int result = taskList[0].Result; 

最終的なノートでは、あなたはParallel.ForEach(...)taskList.ForEach(...)を交換することができるかもしれないが、私はいくつかの不要なオーバーヘッドを紹介すると思います。

+0

なぜ 'Task.Run'を使うのではなく、コンストラクタを使って' Task'sを作成してから 'Start'を呼び出すのですか? – svick

+0

良い点は、私は 'Parallel.ForEach'を使いこなしていましたが、' Task'に正しく戻っていませんでした。最良の解決策は、 'Task.Start'の代わりに' Task.Run'を使うことです。 –

0

正しく学習した場合、リストにあるいくつかのアクションを実行したいだけです。なぜC#で書くのではないのですか?必要なキー(この例では、2及び3)のセットで提示キーですべてのペアを取り、その後、並列的に彼らのアクションを実行します。彼らはそれを読んでどのように

var hs = new HashSet<int> { 2, 3 }; 
var actions = new Dictionary<int, Action>() 
{ 
    {1, Function1}, 
    {2, Function2}, 
    {3, Function3} 
}; 

actions.Where(x => hs.Contains(x.Key)).AsParallel().ForAll(x => x.Value()); 

。かなり明確な、私は推測する。

あなたには、いくつかの値を返したい場合は、それぞれの代わりにActionForAllFuncSelectを使用しています。

関連する問題