Thursday, June 21, 2012

Attempting To Peer Up The Skirt of Non-Blocking I/O in Windows

First A Thank You

Thanks to some fantastic advice I received from Wim Coenen and svick in my other blog post about my little event loop architecture, I've gone back and made some changes that take advantage of .NET's built in Async I/O, rather than my silly BeginInvoked actions.

Great advice like this is why I started this blog. So I can learn.

A Little Digging

Anyhow, after their comments, I started thinking, "How in the world can any I/O be done asynchronously and not block at least one thread?". I mean, a non-blocking main worker thread, sure, but non-blocking I/O? What is there some sort of magic I don't know about where by the OS will just "know" where to start my code back up again?  Well after some digging I came across I/O Completion Ports, which apparently are such magic. Well... mostly.

My (limited) Understanding of I/O Completion Ports and .NET Async I/O

Bearing in mind I just learned about all of this recently, here's my dumbed down version of what's going on here: Microsoft's asynchronous I/O calls in .NET (e.g: FileStream.BeginRead or Socket.BeginReceive) leverage I/O Completion Ports. An  I/O Completion Port is created with a file handle (which are endpoint handles for anything I/O... e.g. sockets, named pipes, file access, etc) and additional information (seemingly in the form of a pointer to something like an object or a method) about what to call upon completion. I followed the calls around in DotPeek starting at FileStream.BeginRead, which only gives me a very fuzzy idea that this is what is happening, when combined with the specs of I/O Completion Ports mentioned above. This is because most of the real magic happens inside native calls I can't see. Frankly, even if I could see them I doubt I have the smarts the figure out what they're doing quickly, or the patience to try to unravel the mystery.

ALE Updated to

As I stated above, I completely overhauled my implementation of non-blocking I/O to leverage .NET's asynchronous I/O methods. Everything should still be up on github. I've also made some changes to how the EventLoop is used. Now to start the EventLoop and being working with it it looks something like this:

EventLoop.Start(() => {
   Server.Create((req, res) => {
      res.Write("<h1>Hello World!</h1>");

I also removed a lot of other asynchronous helpers that would block. I think my future implementations of Async calls that don't leverage .NET native async stuff will simply Pend more events on the event loop. I'll probably implement that soon.

Thanks again to the people who gave me feedback via email, facebook, in person, etc!


  1. In the book "CLR via C#" Jeffrey Richter explains that when you create a FileStream with the FileOptions.Asynchronous flag, it uses an I/O completion port under the covers, when you call BeginRead or BeginWrite.

    If you don't use that flag, the async is 'faked' but simply doing the I/O on a blocked threadpool thread.

    1. Yeah, when digging through the reflected code, I noticed that in there. It changes what it's calling in native code based on those flags. It's interesting (and confusing) stuff to look at.


This form allows some basic HTML. It will only create links if you wrap the URL in an anchor tag (Sorry, it's the Blogger default)