2017-04-21 7 views
0

필자는 함수를 호출하고 싶지만 조건 적으로 호출하려고하는 시나리오가 있습니다. 따라서 아래 코드에서 함수 2와 3 만 호출됩니다. 그러나 Action 부분은 값을 반환하지 않지만 내 경우에는 반환 값을 저장하려고합니다.조건부로 병렬 호출

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#으로 작성하지 않습니까?

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)의 세트에 제시 키로 모든 쌍을합니다. 꽤 분명하다.

일부 값을 반환하려면 각각 ActionForAll 대신 FuncSelect을 사용하십시오.