PInvoke 호출을 이용한 비동기 파일 작업
그냥 잠깐 만들어 보았는데 기록을 남기는 차원에서 써봅니다. ^^
닷넷은 비동기 메서드 호출이 잘 되어 있지만, 가끔은 PInvoke로 직접 해야 하는 경우도 있을 듯 싶어 예제 코드 삼아 만들어 보았습니다.
using Microsoft.Win32.SafeHandles;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateFile(
String pipeName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplate);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteFile(SafeFileHandle hFile, byte[] lpBuffer,
int nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
[In] ref System.Threading.NativeOverlapped lpOverlapped);
public const int FILE_FLAG_OVERLAPPED = 0x40000000;
static void Main(string[] args)
{
EventWaitHandle exitEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
string txt = new string('t', 1024 * 1024 * 600);
byte[] buf = Encoding.ASCII.GetBytes(txt);
while (true)
{
File.Delete(@"C:\temp\test.txt");
using (SafeFileHandle pHandle = CreateFile(@"c:\temp\test.txt",
(uint)FileAccess.ReadWrite,
0,
IntPtr.Zero,
(uint)2,
FILE_FLAG_OVERLAPPED,
IntPtr.Zero))
{
uint written;
NativeOverlapped o = new NativeOverlapped();
using (ManualResetEvent writeEvent = new ManualResetEvent(false))
{
o.EventHandle = writeEvent.SafeWaitHandle.DangerousGetHandle();
Stopwatch st = new Stopwatch();
st.Start();
if (WriteFile(pHandle, buf, buf.Length, out written, ref o) == false)
{
int lastError = Marshal.GetLastWin32Error();
if (lastError == 997) // ERROR_IO_PENDING == 997
{
Console.WriteLine("async");
}
else
{
// Write File Error
Console.WriteLine("Write File Error");
break;
}
WaitHandle[] waitHandles = new WaitHandle[] { writeEvent, exitEvent };
int completeCode = WaitHandle.WaitAny(waitHandles, Timeout.Infinite, false);
if (completeCode == 1) // exitEvent signaled
{
break;
}
}
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
}
Thread.Sleep(1000);
}
}
}
}
아울러, 아래와 같은 자료들이 있으니 읽어보시는 것도 좋겠습니다. ^^
Synchronous and Asynchronous I/O
; https://docs.microsoft.com/en-us/windows/win32/fileio/synchronous-and-asynchronous-i-o
Asynchronous Disk I/O Appears as Synchronous on Windows NT, Windows 2000, and Windows XP
; http://support.microsoft.com/kb/156932
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]