SomeLongJobAsync
starts executing on the thread that called it, and if there is one, the current SynchronizationContext
is saved in the state machine generated by the await
mechanism.
After the first await
completes, the continuation of the method is posted on the current SynchronizationContext
. In a GUI app this means that the continuation executes on the UI thread. In a console app, there is no SyncrhronizatonContext
so the continuation executes on a thread pool thread.
You can check this by printing out the ManagedThreadId
of Thread.CurrentThread
as your program executes. Consider this modified version of your code (which I ran from a console app on Linqpad):
private async void btnSlowPoke_Click(object sender, EventArgs e)
{
await DoItAsync();
}
private async Task<int> SomeLongJobAsync()
{
Console.WriteLine("Start SomeLongJobAsync, threadId = " + Thread.CurrentThread.ManagedThreadId);
for (int x = 0; x < 9; x++)
{
//ponder my existence for one second
await Task.Delay(1000);
Console.WriteLine("Continue SomeLongJobAsync, threadId = " + Thread.CurrentThread.ManagedThreadId);
}
return 42;
}
public async Task<int> DoItAsync()
{
Console.WriteLine("She'll be coming round the mountain, threadId = " + Thread.CurrentThread.ManagedThreadId);
Task<int> t = SomeLongJobAsync(); //<--On what thread does this execute?
Console.WriteLine(" when she comes., threadId = " + Thread.CurrentThread.ManagedThreadId);
return await t;
}
void Main()
{
btnSlowPoke_Click(null, null);
Console.ReadLine();
}
Output from Console App:
She'll be coming round the mountain, threadId = 21
Start SomeLongJobAsync, threadId = 21
when she comes., threadId = 21
Continue SomeLongJobAsync, threadId = 11
Continue SomeLongJobAsync, threadId = 11
Continue SomeLongJobAsync, threadId = 11
Continue SomeLongJobAsync, threadId = 11
Continue SomeLongJobAsync, threadId = 11
Continue SomeLongJobAsync, threadId = 12
Continue SomeLongJobAsync, threadId = 12
Continue SomeLongJobAsync, threadId = 12
Continue SomeLongJobAsync, threadId = 12
As you can see the method started runnung on thread 21, but as each of the await completed it continued on a thread pool thread and not always the same one. In this case 11, 12. If I run this in a Windows Forms app the output is this:
Output from Windows Forms App:
She'll be coming round the mountain, threadId = 8
Start SomeLongJobAsync, threadId = 8
when she comes., threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8
Continue SomeLongJobAsync, threadId = 8