Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent execution of async methods

Tags:

c#

async-await

Using the async/await model, I have a method which makes 3 different calls to a web service and then returns the union of the results.

var result1 = await myService.GetData(source1);
var result2 = await myService.GetData(source2);
var result3 = await myService.GetData(source3);

allResults = Union(result1, result2, result3);

Using typical await, these 3 calls will execute synchronously wrt each other. How would I go about letting them execute concurrently and join the results as they complete?

like image 277
earthling Avatar asked Mar 01 '14 17:03

earthling


People also ask

Are async functions concurrent?

Writing async code may be considered the first step for writing concurrent code. Since async/await is just a pattern, it doesn't make javascript any more concurrent or asynchronous than callbacks did.

Can two async functions run at the same time?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

Is async await concurrent?

It is concurrent, in the sense that many outstanding asychronous operations may be in progress at any time. It may or may not be multithreaded. By default, await will schedule the continuation back to the "current execution context".

Can async method have multiple awaits?

For more information, I have an async / await intro on my blog. So additionally, if a method with multiple awaits is called by a caller, the responsibility for finishing every statement of that method is with the caller.


1 Answers

How would I go about letting them execute in parallel and join the results as they complete?

The simplest approach is just to create all the tasks and then await them:

var task1 = myService.GetData(source1);
var task2 = myService.GetData(source2);
var task3 = myService.GetData(source3);

// Now everything's started, we can await them
var result1 = await task1;
var result1 = await task2;
var result1 = await task3;

You might also consider Task.WhenAll. You need to consider the possibility that more than one task will fail... with the above code you wouldn't observe the failure of task3 for example, if task2 fails - because your async method will propagate the exception from task2 before you await task3.

I'm not suggesting a particular strategy here, because it will depend on your exact scenario. You may only care about success/failure and logging one cause of failure, in which case the above code is fine. Otherwise, you could potentially attach continuations to the original tasks to log all exceptions, for example.

like image 68
Jon Skeet Avatar answered Nov 14 '22 22:11

Jon Skeet