Windows Overlapped I/O and TPL style programming
I really like the manner in which C# async tasks work. And while building Voron, I run into a scenario in which I could really make use of Windows async API. This is exposed via the Overlapped I/O. The problem is that those are pretty different models, and they don’t appear to want to play together very nicely.
Since I don’t feel like having those two cohabitate in my codebase, I decided to see if I could write a TPL wrapper that would provide nice API on top of the underlying Overlapped I/O implementation.
Here is what I ended up with:
Note that I create the file with overlapped enabled, as well as write_through & no buffering (I need them for something else, not relevant for now).
It it important to note that I bind the handle (which effectively issue a BindIoCompletionCallback under the cover, I think), so we won’t have to use events, but can use callbacks. This is much more natural manner to work when using the TPL.
Then, we can just issue the actual work:
As you can see, all the actual details are handled in the helper functions, we can just run the code we need, passing it the overlapped structure it requires. Now, let us look at those functions:
The complexity here is that we need to handle 3 cases:
- Successful completion
- Error (no pending work)
- Error (actually success, work is done in an async manner).
But that seems to be working quite nicely for me so far.