请考虑以下代码
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;
你能猜出打印答案时的CurrentThread.IsThreadPoolThread
是什么吗?
似乎Task.Delay(..)
正在执行此操作,因为如果我删除等待,则答案为False
。但是,我似乎无法发现Delay
实际上将东西放在文档中的线程池中。
这让我想到了更普遍的问题。任务中的内容实际上启动了Run(..)
以外的线程池线程?
修改
用new Task(...)
Ask()
public static async void Ask()
{
int answer = await Answer();
Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
}
产生相同的结果
答案 0 :(得分:3)
正如我在async
/ await
intro帖子中描述的那样,默认情况下await
将捕获当前的“上下文”并使用它来执行延续(await
之后的代码)。此“上下文”为SynchronizationContext.Current
,除非它是null
,在这种情况下为TaskScheduler.Current
。
我还在我的博客上描述了using async
on Console apps。控制台应用不提供SynchronizationContext
,因此“上下文”会回退到TaskScheduler.Current
。由于当前正在执行的Task
正在线程池上运行,TaskScheduler.Current
与TaskScheduler.Default
相同,后者是线程池任务调度程序。
这就是您的代码在线程池线程上恢复的原因。这是正确的行为。