EDIT
I took Jon's comment and retried the whole thing. And indeed, it is blocking the UI thread. I must have messed up my initial test somehow. The string "OnResume exits" is written after SomeAsync
has finished. If the method is changed to use await Task.WhenAll(t)
it will (as expected) not block. Thanks for the input!
I was first thinking about deleting the question because the initial assumption was just wrong but I think the answers contains valuable information that should not be lost.
The original post:
Trying to understand the deeper internals of async-await. The example below is from an Android app using Xamarin. OnResume()
executes on the UI thread.
SomeAsync()
starts a new task (= it spawns a thread). Then it is usingTask.WaitAll()
to perform a blocking wait (let's not discuss now ifWhenAll()
would be a better option).- I can see that the UI is not getting blocked while
Task.WaitAll()
is running. SoSomeAsync()
does not run on the UI thread. This means that a new thread was created.
How does the await
"know" that it has to spawn a thread here - will it always do it? If I change the WaitAll()
to WhenAll()
, there would not be a need for an additional thread as fast as I understand.
// This runs on the UI thread.
async override OnResume()
{
// What happens here? Not necessarily a new thread I suppose. But what else?
Console.WriteLine ("OnResume is about to call an async method.");
await SomeAsync();
// Here we are back on the current sync context, which is the UI thread.
SomethingElse();
Console.WriteLine ("OnResume exits");
}
Task<int> SomeAsync()
{
var t = Task.Factory.StartNew (() => {
Console.WriteLine("Working really hard!");
Thread.Sleep(10000);
Console.WriteLine("Done working.");
});
Task.WhenAll (t);
return Task.FromResult (42);
}