Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What allows a .NET Task to continue after waiting for I/O to complete?

I've been making my way through the book CLR via C#. I'm on Chapter 28, talking about I/O Bound threading.

Here is what I think I understand: Each thread has its own stack. When you're using async and await all the way through to (and including) your IO, the system sends an IO Request Packet (IRP) to your device's IRP Queue. Once the IO Operation is complete, the completed IRP goes back "up" to the thread pool and the thread pool allocates resources to continue running where the async process left off.

My question is this: When a CLR thread hands control over to an IO device, what happens to that CLR thread? Does the stack for that thread get all popped off and returned to the thread pool? And if it gets popped off to be re-used, isn't that stack essential to the continuation of the state of the process that's waiting for the IO to complete? How does the computer know where original CLR thread was (sequentially) when the IO is complete? How does it know where to "pick back up" where it left off?

like image 492
Trevor Avatar asked Oct 26 '25 14:10

Trevor


1 Answers

Is there a pointer somewhere in the CPU that remembers, "hey, when you asked for all this IO, you were here in the program logic, and here's where you need to start again"?

No. The resuming of asynchronous I/O is done through a chain of callbacks. The IOCP calls back into a completion routine that is run on a .NET I/O thread pool thread, which (eventually) completes the Task, which causes task continuations to run, which resumes executing the async method. For more information, see my blog post There Is No Thread.

Also note that async methods do not necessarily resume on the same thread. For more info on how await resumes on a particular context, see my blog post Async and Await.

like image 123
Stephen Cleary Avatar answered Oct 29 '25 02:10

Stephen Cleary