Please consider the following code
public static async Task<int> Answer()
{
await Task.Delay(1000);
return 42;
}
static void Main(string[] args)
{
for (int j = 0; j < 20; j++)
{
Console.WriteLine(j +" " + Thread.CurrentThread.IsThreadPoolThread);
if (j == 1)
{
new Task( async ()=>
{
int answer = await Answer();
Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
}).Start();
}
Thread.Sleep(200);
}
return;
Can you guess what the CurrentThread.IsThreadPoolThread when printing answer is?
It appears that Task.Delay(..) is doing it, for if I remove await, then the answer is False. However, I can not seem to find that Delay actually puts stuff on the thread pool in the documentation.
This brings me to the more general question. What in Task does actually start up a thread pool thread besides Run(..)?
Edit:
Replacing new Task(...) with Ask()
public static async void Ask()
{
int answer = await Answer();
Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
}
yields the same result
As I describe in my
async/awaitintro post, by defaultawaitwill capture the current “context” and use that to execute the continuation (the code after theawait). This “context” isSynchronizationContext.Currentunless it isnull, in which case it isTaskScheduler.Current.I also describe using
asyncon Console apps on my blog. Console apps do not provide aSynchronizationContext, so the “context” falls back toTaskScheduler.Current. Since the currently-executingTaskis running on the thread pool,TaskScheduler.Currentis the same asTaskScheduler.Default, which is the thread pool task scheduler.This is why your code is resuming on a thread pool thread. It’s the correct behavior.