Async thread body loop, It just works, but how?

The thread is indeed terminated very quickly.

But since the Thread constructor doesn’t accept an async lambda what you got there is an async void delegate.

The original thread will end and the continuation (the rest after the await) will be posted to the ThreadPool and eventually run on another thread.

You can test that by checking the thread id:

var thread = new Thread(async () =>
{
    while (true)
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        await SomeLengthyTask();
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    }
});
thread.Start();
thread.Join();

Console.ReadLine();

Output:

3
5
5
...
5

To make the example simpler let’s assume you have this Run method:

void Run(Action action)
{
    action();
}

And you call it with your async delegate

Run(async () => 
{
    while(true) 
    {
      await SomeLengthyTask();
      ...
    }
});

The execution of Run will complete almost immediately when it reaches the first await and returns. The rest of the async delegate will continue on the ThreadPool with another thread.


Generally, each time you reach an await in the execution of an async method the thread is lost and the continuation (the rest after the awaited task completes) will be posted to the ThreadPool (unless if there’s a SynchronizationContext present, like in the UI thread). It may be that it execution will be on the same thread (as in my example with 5) but it also may not.

In your case the thread you create explicitly isn’t part of the ThreadPool so it will definitely be terminated and the rest will run on a different thread.

Leave a Comment