As promised, I've created Buffered version of OverlappedStream. It has a byte[] buffer instead of unmanaged IntPtr, as there are no restrictions on memory alignment when FILE_FLAG_NO_BUFFERING is not used.
Also, in unbuffered version both WriteFileGather and ReadFileScatted functions were implemented. The restrictions for buffer size and alignment are different for Gather/Scatter operations: buffers should be of system page size and have the same alignment. OverlappedStreamUnbuffered.SystemPageSize property returns this value and it has to be used for buffer allocations.
Some examples
OverlappedStreamUnbuffered stream = new OverlappedStreamUnbuffered( path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Read, OverlappedStreamUnbuffered.UnbufferedFileOptions.None); IntPtr[] buffers = new IntPtr[BUFFERS]; for (int i = 0; i < buffers.Length; i++) { // allocate aligned buffers with VirtualAlloc or custom class buffers[i] = UnmanagedBufferPool.Alloc((int)OverlappedStreamUnbuffered.SystemPageSize); } IAsyncResult ar = stream.BeginReadScatter(buffers, startAddr, null, null); uint bytesRead = OverlappedStream.EndOperation(ar, throwOnError); // it is also possible to use more common syntax: // stream.EndRead(ar);
Final notes
Asynchronous file access is often tricky, same as any multithreaded programming. One of non-obvious behaviours is that thread exit aborts pending IO operations started in this thread. It is well described here: http://www.beefycode.com/post/Overlapped-IO-Aborted-by-Terminating-Thread.aspx.Therefore always wait for completion of all async operations even if they are initiated from a thread pool thread.
Full source code can be found on https://overlappedstream.codeplex.com/
Hey Michael. I am trying to get OverlappedStreamUnbuffered.BeginWriteGather to work but I get the error 87. Error 87 means that memory is not pinned+aligned...but I use GCHandle.Alloc(bytearr, GCHandleType.Pinned) and AddrOfPinnedObject() but it does not seem to work. Question: how does you unmanagedpool pin byte arrays?
ReplyDelete