Skip to content

Instantly share code, notes, and snippets.

@dschenkelman
Created May 9, 2014 04:24
Show Gist options
  • Save dschenkelman/a5f8343f78492397f73b to your computer and use it in GitHub Desktop.
Save dschenkelman/a5f8343f78492397f73b to your computer and use it in GitHub Desktop.
Asynchronous I/O in C#: I/O Completion Ports
const uint Flags = 128 | (uint)1 << 30;
var fileHandle = Interop.CreateFile("test.txt", (uint)1 << 31, 0, IntPtr.Zero, 3,
/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED */ Flags,
IntPtr.Zero);
Interop.CreateIoCompletionPort(
fileHandle,
completionPortHandle,
(uint)fileHandle.ToInt64(),
0);
// create completion port
var completionPortHandle = Interop.CreateIoCompletionPort(new IntPtr(-1), IntPtr.Zero, 0, 0);
public class IOCompletionWorker
{
public unsafe void Start(IntPtr completionPort)
{
while (true)
{
uint bytesRead;
uint completionKey;
NativeOverlapped* nativeOverlapped;
var result = Interop.GetQueuedCompletionStatus(
completionPort,
out bytesRead,
out completionKey,
&nativeOverlapped,
uint.MaxValue);
var overlapped = Overlapped.Unpack(nativeOverlapped);
if (result)
{
var asyncResult = ((FileReadAsyncResult)overlapped.AsyncResult);
asyncResult.ReadCallback(bytesRead, asyncResult.Buffer);
}
else
{
ThreadLogger.Log(Interop.GetLastError().ToString());
}
Overlapped.Free(nativeOverlapped);
}
}
}
var readBuffer = new byte[1024];
uint bytesRead;
var overlapped = new Overlapped
{
AsyncResult = new FileReadAsyncResult()
{
ReadCallback = (bytesCount, buffer) =>
{
var contentRead = Encoding.UTF8.GetString(buffer, 0, (int)bytesCount);
},
Buffer = readBuffer
}
};
NativeOverlapped* nativeOverlapped = overlapped.UnsafePack(null, readBuffer);
Interop.ReadFile(fileHandle, readBuffer, (uint)readBuffer.Length, out bytesRead, nativeOverlapped);
var completionPortThread = new Thread(() => new IOCompletionWorker().Start(completionPortHandle))
{
IsBackground = true
};
completionPortThread.Start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment