Parallel.Invoke() without waiting on execution to finish
Solution 1
If you want to wait for a piece of code to finish executing, instead of using Parallel.Invoke, why not just call the code directly?
Well normally you'd call Parallel.Invoke
with multiple pieces of work. If you execute those pieces of work in series, it'll (probably) take longer than executing them in parallel.
"Execute in parallel" isn't the same as "execute in the background" - you appear to be looking for the latter, but that's not what Parallel.Invoke
is about.
If you just want to start tasks, use Task.Run
(or Task.Factory.StartNew
prior to .NET 4.5). Parallel.Invoke
is specifically for executing a bunch of actions in parallel, but then waiting for those parallel actions to complete.
As a concrete example, you can perform a sort by partitioning, then recursively sorting both sides of the pivot in parallel. Doing this will make use of multiple cores, but you would usually still want to wait until that whole sort had completed before you proceed.
Solution 2
Simply wrap your Parallel.Invoke
call in a Task
if you don't want to wait for completion.
Task.Factory.StartNew( () =>
{
Parallel.Invoke( <one or more actions> );
} );
Solution 3
Are you looking for something like this?
async Task ParallelInvokeAsync(Action[] actions)
{
var tasks = actions.Select(a => Task.Run(a));
await Task.WhenAll(tasks);
}
Background execution:
ParallelInvokeAsync(actions);
MessageBox.Show("I'm working");
Background execution with blocking, very similar to Parallel.Invoke
:
ParallelInvokeAsync(actions).Wait();
MessageBox.Show("I'm dome working");
Anshul
ASP.NET Developer by profession. Technologist by hobby. I love delving into software and hardware technologies to come up with solutions for the community, myself included.
Updated on June 05, 2022Comments
-
Anshul almost 2 years
Please know that I'm aware that Parallel.Invoke() is meant for task synchronization. My question is this:
Is there a way to call an anonymous method using something like Parallel.Invoke in which the call does NOT wait on the execution to finish?
I thought the whole point of parallel execution (or parallel invokation) is to NOT have to wait for the task to finish. If you want to wait for a piece of code to finish executing, instead of using Parallel.Invoke, why not just call the code directly? I guess I just don't understand the point of Parallel.Invoke. The documentation just says what it does, but doesn't mention any use-cases when this would be more useful than just calling the code directly.
-
Anshul about 10 yearsYou're right, I was under the impression that executing in parallel is the same as executing in background. Can you tell me what the difference is and how it applies to Parallel.Invoke? Or point me to a resource that can help me understand the difference?
-
Jon Skeet about 10 years@Anshul: Executing in parallel is simply using multiple cores to accomplish a goal. That can be done in a "fire and forget" way, but it's not always. See my edit for a concrete example of when it's useful to parallelize work without making it a background task.
-
Anshul about 10 yearsIf I have 2 Parallel.Invokes in sequeunce, wouldn't the 2nd one wait until the first one is finished to be called? In that case, how would you execute the multiple pieces of code in parallel using Parallel.Invoke?
-
L.B about 10 years@Anshul
Parallel.Invoke(action1,action2);
both actions will run in parallel but Parallel.Invoke will wait both of them to finish. Suppose their execution times aret1
andt2
.Parallel.Invoke
will waitmax(t1,t2)
seconds. -
Anshul about 10 yearsWhat if I was to do Task.Factory.StartNew(()=>{//do whatever}); instead of using Parallel.Invoke? Wouldn't it have the same effect since you're starting a new task essentially?
-
Moho about 10 yearsSure, you would need to start a new task for each action you wish to execute in parallel, though.
-
Anshul about 10 yearsUnderstood. Seems like I was misunderstanding the reason behind Parallel.Invoke().
-
Moho about 10 yearsIf you're simply looking to execute an action on a background thread, create a task for that action.
Parallel.Invoke
is if you want to execute multiple actions 'simultaneously' -
Moho about 10 yearsand then synchronize after their execution completes
-
Anshul about 10 years@L.B That makes sense now. I just had the wrong idea in my head about what Parallel.Invoke is supposed to do.
-
Anshul about 10 yearsI suppose that would work as well. I just needed something that makes use of the TPL and executes a piece of code in parallel with the current line of execution. By that I mean that the current line of execution should not wait on the parallelized task to finish. Task.Factor.StartNew(()=>{}) satisfies this requirement. I wanted to keep the call succint mainly.
-
Anshul about 10 years@JonSkeet Task.Run is essentially what I was looking for. Thank you.
-
noseratio about 10 years@Anshul, how you use it depends on the caller. I updated the answer to illustrate it. Theoretically,
Task.Factory.StartNew(() => Parallel.Invoke(actions))
would create one more thread than theParallelInvokeAsync(actions)
above. -
Microsoft Developer over 9 yearsBest not to use StartNew use Task.Run! I see this mistake all the time.
-
Gil Sand about 8 yearsHey @JonSkeet, is there a way to execute code when the last parallel task has finished ? Right now i have several
async () => await Foo();
in the Parallel.Invoke, and I can't seem to find the sweet spot. It either takes the additive complete time of each consecutive call, or less than a second and clearly skips the waiting. -
Jon Skeet about 8 years@Zil: It sounds like you should ask a new question. It's slightly unusual (IMO) to use
Parallel.Invoke
and async/await at the same time... -
Gil Sand about 8 yearsYou're right. I'm confused, i'll write a specific question :)