2017-04-21 25 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>我們可以並行運行它們後得到的結果回來。

我在下面的示例中添加了Task而不是Parallel以使這些功能同時運行並允許您存儲結果。我假設int爲函數1,2和3的返回類型 - 您可以將其更改爲適合您的需求。

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; 

最後一點,你可以交換taskList.ForEach(...)Parallel.ForEach(...),但我認爲,這將介紹一些不必要的開銷。

+0

爲什麼使用構造函數創建'Task',然後調用'Start',而不是隻使用'Task.Run'? – svick

+0

好點,我在使用'Parallel.ForEach'搞亂了,但沒有正確切換回'Task'。最好的解決方案是使用'Task.Run'而不是'Task.Start'。 –

0

如果我學得對,你只是想執行列表中存在的一些動作。爲什麼不把它寫在C#上呢?

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()); 

如何他們閱讀:採取一切對與集合所需要的密鑰(在本實施例2和3)的呈現鍵,然後以並行的方式執行他們的動作。我想很清楚。

如果要返回一些值,分別使用FuncSelect而不是ActionForAll