我想问一下这个任务是否完成了.延迟调用任务.运行在下面,这是线程id更改的原因,还是背后有不同的逻辑?
async Task Main()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //11
await Task.Delay(200);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //22
}
我想问一下这个任务是否完成了.延迟调用任务.运行在下面,这是线程id更改的原因,还是背后有不同的逻辑?
async Task Main()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //11
await Task.Delay(200);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //22
}
不Task.Delay
号不叫Task.Run
号.它只返回一个在指定的持续时间后完成的Task
,并调用ThreadPool
上附加到它的任何continuations.它在内部使用System.Threading.Timer
.其实现如下所示:
public class Task
{
public static Task Delay(int millisecondsDelay)
{
var tcs = new TaskCompletionSource();
_ = new Timer(_ => tcs.SetResult(), null, millisecondsDelay, -1);
return tcs.Task;
}
}
因此,当您在Task.Delay
中输入await
时,await
之后的继续在调用Timer
回调的同一个线程上运行,这恰好是一个ThreadPool
线程.
Note:以上述实现为例.这不是实际的实现,也不能保证正确工作.Timer
实例没有存储在任何地方,因此在调用回调之前,它可能会被垃圾收集,导致永远无法完成Task
.