I have a situation where I want to fire off a user-defined number of tasks asynchronously and wait for all of them to complete. Simplified, here's what I'm dealing with:
[TestMethod]
public async Task Start() {
var numDrivers = 2;
while (numDrivers != 0) {
var rnd = new Random();
var r = rnd.Next(itemArray.Count);
var target = itemArray[r];
var proxyDriver = GetProxiedDriver();
Task.Run(() => HandleIntro(proxyDriver, target));
numDrivers--;
}
}
For some context - these are Selenium webdrivers getting spun up to run some UI tests. I see the browsers pop up, but as soon as the last Task.Run()
completes, all execution stops. How do I fire off n
drivers to run asynchronously while waiting for them all to complete before stopping execution?
I've tried await Task.Run(() => HandleIntro(proxyDriver, target));
but this awaits the task and they don't run simultaneously.
HandleIntro:
private async Task HandleIntro(FirefoxDriver driver, string target) {
// do stuff
}
The correct way to await multiple tasks is the Task. WhenAll method: await Task. WhenAll(first, second); . Then you can await them individually to get their results, because you know that all have completed successfully.
await hides all this complexity from you, and it allows you to await the same task in ten different places (very useful for e.g. asynchronous lazy initialization). can I be assured that the method pointed by task wont be executed twice even if the task is running or ran already ? @BilalFazlani Yes, you can.
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.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .
It's rather simple with async-await
. You have Task.WhenAll
which itself returns an awaitable which can be asynchronously waited for all tasks to complete:
[TestMethod]
public async Task Start()
{
var numDrivers = 2;
List<Task> tasks = new List<Task>();
while (numDrivers != 0)
{
var rnd = new Random();
var r = rnd.Next(itemArray.Count);
var target = itemArray[r];
var proxyDriver = GetProxiedDriver();
tasks.Add(Task.Run(() => HandleIntro(proxyDriver, target)));
numDrivers--;
}
await Task.WhenAll(tasks);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With