Reputation: 7458
I have a queue which have like 144 items in it. Each queue element is a request. I am trying to increase the performance of the processing by trying to run the code in parallel. I call performaction(request) method. Which instantiate an object and pass the request to it and perform an action. I can run this action parallely since these requests are independent and the action results of the requests are also independent of each other. First I tried
foreach(var request in queue.Values)
Parallel.Invoke(() =>PerformAction(request);
then I tried for the same foreach.
var task = new Task(() => PerformAction(request));
task.Start();
and outside the foreach I have
Task.WaitAll();
When the run the program the parallel.invoke took almost 3 second to complete while Task took almost 0.005s to complete.
I have the following questions:
Upvotes: 2
Views: 3871
Reputation: 15618
The problem in your code is that Task.WaitAll()
doesn't work as you intended. You've saved and started a task:
var task = new Task(() => PerformAction(request));
task.Start();
But you haven't kept a reference to each task to pass to WaitAll
. You're meant to save all the tasks in an array and then pass that array to WaitAll
. So your program executes 'fast' with Tasks because it's not waiting to finish.
Your questions:
See above for why Parallel.Invoke
took more time - because it actually run. However, you're also not using it correctly. Parallel.Invoke takes an array of actions (Actions[]
) and tries to run them all in parallel. You're calling it multiple times with a single action each time. I'm not even sure how your code compiles. I believe what you want is:
Parallel.ForEach(queue.Values, request => PerformAction(request))
You are creating a new task for each request, but that doesn't map one to one with a thread. By default, tasks use the thread pool.
Task.WaitAll(tasks)
does wait for all tasks
to finish. But it doesn't if you don't pass it anything. Again, this shouldn't compile as you have it.
Upvotes: 9