Waits for another thread to be created internally before switching to the same thread as the caller (for the UI application)

What I know about async / await is that when the task completes, the continuation is done in the same context when the wait was called, which in my case would be a UI thread. But my question is whether it creates a new thread (internally) after I / O is completed and before moving to the same user interface thread.

I am sharing a piece of code. If I click this button once, it will show that the available thread is 1023 before waiting, but after that the available threads dropped to 1022. Although, when I check the thread ID, it is the same as the 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, the next time I click on this button, the number of available threads remains 1023 (before and after waiting).

+6
source share
3 answers

But my question is: does it create a new thread (internally) after I / O is completed and before moving to the same user interface thread.

Other threads may be temporarily used, but you do not need to worry about it.

In particular, I / O on .NET typically goes through the I / O completion port, which is part of the thread pool. I / O streams are automatically added and removed as needed. Quite often, I / O requires additional work before it is really ready to return to your code (for example, parsing HTTP response headers), so most of the BCL I / O code will actually use the I / O stream just a queue to work in thread pool. Therefore, the thread workflow thread is often used (briefly) using input / output code.

In addition, in this particular example, I believe there is a separate timer thread that integrates system timers. Naturally, this is an implementation detail and is subject to change.

So, in general, other threads can be created / destroyed / temporarily used, but you do not need to worry about that. They are all managed by BCL or .NET runtime in a very efficient way, choosing a balance between thread reuse (minimizing outflow) and minimizing resource use (especially memory).

+4
source

I assume you intended to fall to 1022.

In general, I think it depends on how the asynchronous call is made. Disk and network calls are returned to the stream from the I / O completion pool of threads. It appears that Task.Delay returning to the regular workflow.

You can change the line to await Task.Delay(5000).ConfigureAwait(false); , set a breakpoint after it and look at the Threads window to see it directly.

It will end in the workflow no matter where you call it from. await does not pass the calling context to the function performing the async operation; it adds an extra step to return to the user interface thread when this is done.

I would not read too much to track the exact number here; The CLR has its own algorithms that control the size of the thread pool, and those can go from release to release. And I would not talk about this using another thread: in a regular application, it will simply reuse the existing thread from the pool, and the operation will be very fast.

0
source

Let me analyze your code implementation

 int x, y; ThreadPool.GetAvailableThreads(out x, out y); textBox1.Text = x.ToString()+"..."+y.ToString(); 

In UI Thread you can get Number of threads in ThreadPool .

Now when the following call is made:

 await Task.Delay(5000); 

It calls ThreadPool thread to start Delay , which will be the duration of the Async call. Now this is not the standard behavior of an Async call, as the Async call sent for IO runs on IO completion ports , associated with the queue hardware for making IO calls and the thread pool thread is not involved, but in this case you explicitly use ThreadPool thread for processing, which has nothing to do with Async per se.

This explains the reason that at the moment you go beyond the await post Delay, in ThreadPool it offers less than 1 thread, since the used thread has not yet returned to the pool, at least the pool does not take into account it is available until this time.

To do a clean Async-Await test using a standard Async call from Microsoft , such as Read / Write File Async or Network IO Async , which will not trigger a Threadpool thread, and you will see exactly the same number as expected, which will clarify Async-Await in the real sense

0
source

All Articles