Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async - wait for two async tasks to finish

I have two function calls that are run in my code, and when both are done, the function ProcessFiles is run. Like this:

  byte[] file1 = doSomething();
  byte[] file2 = doSomethingElse();

  ProcessFiles(file1, file2);

These two functioncalls DoSomething and DoSomethingElse are completely seperate, and I was thinking of running these in a different thread so they are run simultaneously. However, I need to process the results (file1 and file2) when both are done.

I guess async await (or its VB.NET equivalent) is the way to go here, but for the life of me, I can't find any good examples that showcase this. Maybe I'm using the wrong search queries, but so far I haven't been able to get a good example. Can anyone point me in the right direction please?

like image 800
Steven Lemmens Avatar asked Dec 03 '25 23:12

Steven Lemmens


2 Answers

Yes, you can do this easily with async/await. For example:

// If you don't have async equivalents, you could use Task.Run
// to start the synchronous operations in separate tasks.
// An alternative would be to use Parallel.Invoke
Task<byte[]> task1 = DoSomethingAsync();
Task<byte[]> task2 = DoSomethingElseAsync();

byte[] file1 = await task1;
byte[] file2 = await task2;
ProcessFiles(file1, file2);

The important thing is that you don't await either task until you've started both of them.

like image 138
Jon Skeet Avatar answered Dec 06 '25 14:12

Jon Skeet


I was thinking of running these in a different thread... I guess async await

Note that async/await does not imply any particular kind of threading. Async/await deals with asynchronous code, not parallel code. For more information, see my async intro.

However, you can use Task.Run to execute code on a thread pool thread, and then you can use Task.WhenAll to (asynchronously) wait for them both to complete:

var task1 = Task.Run(() => doSomething());
var task2 = Task.Run(() => doSomethingElse());

var results = await Task.WhenAll(task1, task2);
ProcessFiles(results[0], results[1]);

Alternatively, since your code is already synchronous, you can use WaitAll. Note that your error handling is different with parallel code (you need to be prepared for AggregateException):

var task1 = Task.Run(() => doSomething());
var task2 = Task.Run(() => doSomethingElse());

Task.WaitAll(task1, task2);
ProcessFiles(task1.Result, task2.Result);
like image 32
Stephen Cleary Avatar answered Dec 06 '25 12:12

Stephen Cleary