Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does await create another thread internally before shifting to the same thread as the caller (for UI application)

What I know about async/await is that when the task completes, the continuation is run on the same context when the await was called, which would, in my case, be the UI thread. But my question is, does it create a new thread (internally) after IO is complete and before moving to the same UI thread.

I am sharing a piece of code. If I click on this button once, It shows that available thread is 1023 before executing await, but after that, available threads dropped to 1022. Although When I check the thread id, it is the same as UI thread.

    private async void button1_ClickAsync(object sender, EventArgs e)
    {
        int x, y;
        ThreadPool.GetAvailableThreads(out x, out y);
        textBox1.Text = x.ToString()+"..."+y.ToString();
        await Task.Delay(5000);
        ThreadPool.GetAvailableThreads(out x, out y);
        textBox1.Text = x.ToString() + "..." + y.ToString();
    }

But interestingly, next time when I click on this button, number of available threads remains 1023 (before and after await).

like image 411
Pragmatic Avatar asked Sep 15 '16 01:09

Pragmatic


People also ask

Does await create a new thread?

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread.

Does async await run on separate thread?

An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method. The async and await keywords don't cause additional threads to be created.

Does async run on another thread?

No, it does not. It MAY start another thread internally and return that task, but the general idea is that it does not run on any thread.

Does await pause the thread?

Think of “await” as an “asynchronous wait”. The async method pauses until the awaitable is complete (so it waits), but the actual thread is not blocked (so it's asynchronous).


1 Answers

But my question is, does it create a new thread (internally) after IO is complete and before moving to the same UI thread.

Other threads may be temporarily used, but you don't need to worry about that.

In particular, I/O on .NET generally goes through an I/O completion port that is part of the thread pool. I/O threads are automatically added and removed as necessary. Fairly often, the I/O has some additional work to do before it actually is ready to return to your code (e.g., parsing HTTP response headers), so a lot of the BCL I/O code will actually use the I/O thread just to queue work to the thread pool. So a thread pool worker thread is often used (briefly) by I/O code.

Also, in this particular example, I believe there's a separate timer thread as well, that coalesces system timers. Naturally, this is an implementation detail and subject to change.

So, in summary, other threads may be created/destroyed/temporarily used, but you don't have to worry about it. They're all managed by the BCL or .NET runtime in a very efficient manner, striking a balance between reusing threads (minimizing churn) and minimizing resource use (especially memory).

like image 192
Stephen Cleary Avatar answered Sep 29 '22 13:09

Stephen Cleary