Reputation: 585
I am trying to implement code to run two tasks in parallel. The tasks return values which are assigned to two different local variables and that will need to use after the tasks are completed.
This what I have:
var return1 = new ReturnType1();
var task1 = Task.Run(async() =>
{
return1 = await MyAPI.GetSomeData(param1);
});
var return2 = new ReturnType2();
var task2 = Task.Run(async() =>
{
return2 = await MyApi.GetSomeOtherData(param2);
});
var tasks = new List<Task>();
tasks.Add(task1);
tasks.Add(task2);
await Task.WhenAll(tasks);
bool isNotNullReturn1 = return1 != null;
bool isNotNullReturn2 = return2 != null;
// And just to check return types have been assigned
Console.WriteLine($"{isNotNullReturn1.ToString(), {isNotNullReturn2.ToString()}}");
Will these tasks run in parallel?
I am not sure what happens with the await in the individual Tasks? Will they run on separate background threads, each awaiting for their respective results in parallel and thus behave as desired? Or will they somehow run in sequance because the await?
Separate question but my research hasn't made this clear. Does "await" always create a separate thread than the UI, same as "Task.Run" ?
And is this the correct way to do it? Please advise/correct.
Upvotes: 0
Views: 1209
Reputation: 456587
Will these tasks run in parallel?
They will run concurrently, yes.
I am not sure what happens with the await in the individual Tasks? Will they run on separate background threads, each awaiting for their respective results in parallel and thus behave as desired? Or will they somehow run in sequance because the await?
await
operates in sequence within its current method. In this case, that method is just the delegate passed to Task.Run
. So the await
in one delegate has nothing to do with the await
in another delegate.
Separate question but my research hasn't made this clear. Does "await" always create a separate thread than the UI, same as "Task.Run" ?
No.
And is this the correct way to do it? Please advise/correct.
Currently, this code is a bit convoluted:
var task1 = Task.Run(async() =>
{
return1 = await MyAPI.GetSomeData(param1);
});
It's sending work (the delegate) to a background thread, and then that work behaves asynchronously (allowing the background thread to return to the thread pool). Assuming that GetSomeData
is truly asynchronous (i.e., not blocking the calling thread), then the background thread is superfluous; the Task.Run
isn't needed.
The other suggestion of note is that asynchronous code tends to be cleaner if you return results rather than set them as a side effect of executing the code.
I would write it like this:
var task1 = MyAPI.GetSomeData(param1);
var task2 = MyApi.GetSomeOtherData(param2);
await Task.WhenAll(task1, task2);
var return1 = await task1;
var return2 = await task2;
Upvotes: 2