Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created February 19, 2012 04:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mattpodwysocki/1862069 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/1862069 to your computer and use it in GitHub Desktop.
Async I/O read in C#
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32.SafeHandles;
namespace AsyncIO
{
internal static class NativeMethods
{
[Flags]
internal enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
WriteThrough = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
internal delegate void FileIOCompletionRoutine(
uint dwErrorCode,
uint dwNumberOfBytesTransfered,
ref NativeOverlapped lpOverlapped);
[DllImport("kernel32.dll")]
internal static extern uint SleepEx(uint dwMilliseconds, bool bAlertable);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern SafeFileHandle CreateFile(
string lpFileName,
[MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
[MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
[MarshalAs(UnmanagedType.U4)] EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool ReadFileEx(
SafeFileHandle hFile,
[Out] byte[] lpbuffer,
[In] uint nNumberOfBytesToRead,
[In, Out] ref NativeOverlapped lpOverlapped,
[In] FileIOCompletionRoutine lpCompletionRoutine);
}
class Program
{
private static SafeFileHandle _fileHandle;
internal static void OnReadComplete(
uint dwErrorCode,
uint dwNumberOfBytesTransfered,
ref NativeOverlapped lpOverlapped)
{
var code = dwErrorCode;
var bytes = dwNumberOfBytesTransfered;
var overlapped = lpOverlapped;
Console.WriteLine("Bytes read: {0}", bytes);
Console.WriteLine("Error Code: {0}", code);
_fileHandle.Close();
}
static void Main(string[] args)
{
const string fileName = @"C:\Dev\license.txt";
_fileHandle = NativeMethods.CreateFile(
fileName,
FileAccess.Read,
FileShare.Read,
IntPtr.Zero,
FileMode.Open,
NativeMethods.EFileAttributes.Overlapped,
IntPtr.Zero);
var overlapped = new NativeOverlapped();
var bytes = new byte[4096];
var read = NativeMethods.ReadFileEx(_fileHandle, bytes, (uint)bytes.Length, ref overlapped, OnReadComplete);
Console.WriteLine("Read? {0}", read);
NativeMethods.SleepEx(0, true);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment