I would like to ask whether the Task.Delay calls Task.Run underneath and it is reason of change of thread id or there is different logic behind it?
async Task Main()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //11
await Task.Delay(200);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //22
}
CodePudding user response:
No, the Task.Delay
doesn't call the Task.Run
underneath. It just returns a Task
that completes after the specified duration, and invokes any continuations that are attached to it on the ThreadPool
. It uses a System.Threading.Timer
internally. Its implementation looks like this:
public class Task
{
public static Task Delay(int millisecondsDelay)
{
var tcs = new TaskCompletionSource();
_ = new Timer(_ => tcs.SetResult(), null, millisecondsDelay, -1);
return tcs.Task;
}
}
So when you await
the Task.Delay
, the continuation after the await
runs on the same thread where the Timer
callback is invoked, which happens to be a ThreadPool
thread.
Note: The above implementation is presented as an example. It's not the actual implementation, and it's not guaranteed to work correctly. The Timer
instance is not stored anywhere, and so it might become garbage collected before the callback is invoked, resulting in a never-completing Task
.