Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly write Parallel.For with async methods

How would I structure the code below so that the async method gets invoked?

Parallel.For(0, elevations.Count(), delegate(int i) {    allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels)); }); 
like image 638
Filling The Stack is What I DO Avatar asked Oct 09 '13 22:10

Filling The Stack is What I DO


People also ask

How do you call async in parallel?

Use Promise. all for the parallel function calls, the answer behaviors not correctly when the error occurs. Caveat: It doesn't matter if the await calls are on the same line or on different lines, so long as the first await call happens after all of the asynchronous calls.

Is parallel for async?

When you run something asynchronously it means it is non-blocking, you execute it without waiting for it to complete and carry on with other things. Parallelism means to run multiple things at the same time, in parallel. Parallelism works well when you can separate tasks into independent pieces of work.

Do async tasks run in parallel?

There is no parallelism here, as the “async Task” does not automatically make something run in in parallel. This will spawn 2 threads, run them simultaneously, and return when both threads are done. This will create a list of Tasks to be run at the same time.

Can we achieve parallel programming through async and await?

so an asynchronous programming implemented using async and await in c# 4.5 can also be considered parallel programming? I would say yes.


2 Answers

Parallel.For() doesn't work well with async methods. If you don't need to limit the degree of parallelism (i.e. you're okay with all of the tasks executing at the same time), you can simply start all the Tasks and then wait for them to complete:

var tasks = Enumerable.Range(0, elevations.Count())     .Select(i => BuildSheetsAsync(userID, elevations[i], includeLabels)); List<Bitmap> allSheets = (await Task.WhenAll(tasks)).SelectMany(x => x).ToList(); 
like image 78
svick Avatar answered Sep 20 '22 04:09

svick


I'd recommend you to take a look at this question I asked a few days ago and ended-up answering myself, basically I was looking for a parallel and asynchronous ForEach method.

The method uses SemaphoreSlim to process things in parallel and it accepts asynchronous methods as an input action.

You might also want to take a look at the two links I have provided at the end of my answer, they have been really helpful for realizing such behavior and they also contain another way of doing this using a Partitioner instead.

Personally, I didn't like the Parallel.For because it's a synchronous call as explained in the links I've given; I wanted it all 'async' :-)

Here it is : Asynchronously and parallelly downloading files

like image 27
aybe Avatar answered Sep 22 '22 04:09

aybe