请看下面的代码:
产生相同的结果。
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(..)
在起作用,因为如果我去掉 await,那么答案就是 False
。但是,我似乎在文档中找不到 Delay
实际上将东西放在线程池中的相关信息。
这带我来到更一般的问题。除了 Run(..)
之外,Task 中什么实际上会启动一个线程池线程呢?
编辑:
将 new Task(...)
替换为 Ask()
public static async void Ask()
{
int answer = await Answer();
Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
}
产生相同的结果。
Task.ConfigureAwait(false)
,即将其设置为 false 将始终在 TP 线程上执行回调函数? - kasperhjnew Task
...Start
时没有提供TaskScheduler
,它将在线程池上运行;这与Task.Run
非常相似。是的,如果你使用ConfigureAwait(false)
等待一个尚未完成的操作,那么它将始终在线程池上执行后续操作。 - Stephen Clearynew Task.Start(..)
替换掉了。结果是一样的。我认为这是因为对Task.Start(..)
的调用现在是隐式的。结论是通常所有任务都会在没有显式请求的情况下运行在线程池上吗?你觉得有可能让对Answer(..)
的调用变成阻塞的吗? - kasperhjAnswer
将在控制台应用程序的主线程上开始执行,该线程仍然没有SynchronizationContext
或TaskScheduler
,因此它仍将使用TaskScheduler.Default
。这就是为什么您看到相同的结果,这仍然是正确的原因。没有隐式调用Task.Start
。 - Stephen Cleary