public unsafe void MultipleOperationsOverMultipleHandles()
{
const int DATA_SIZE = 2;
SafeHandle handle1 = HandleFactory.CreateAsyncFileHandleForWrite(@"MultipleOperationsOverMultipleHandle1.tmp");
SafeHandle handle2 = HandleFactory.CreateAsyncFileHandleForWrite(@"MultipleOperationsOverMultipleHandle2.tmp");
ThreadPoolBoundHandle boundHandle1 = ThreadPoolBoundHandle.BindHandle(handle1);
ThreadPoolBoundHandle boundHandle2 = ThreadPoolBoundHandle.BindHandle(handle2);
OverlappedContext result1 = new OverlappedContext();
OverlappedContext result2 = new OverlappedContext();
byte[] data1 = new byte[DATA_SIZE];
data1[0] = (byte)'A';
data1[1] = (byte)'B';
byte[] data2 = new byte[DATA_SIZE];
data2[0] = (byte)'C';
data2[1] = (byte)'D';
PreAllocatedOverlapped preAlloc1 = new PreAllocatedOverlapped(OnOverlappedOperationCompleted, result1, data1);
PreAllocatedOverlapped preAlloc2 = new PreAllocatedOverlapped(OnOverlappedOperationCompleted, result2, data2);
for (int i = 0; i < 10; i++)
{
NativeOverlapped* overlapped1 = boundHandle1.AllocateNativeOverlapped(preAlloc1);
NativeOverlapped* overlapped2 = boundHandle2.AllocateNativeOverlapped(preAlloc2);
fixed (byte* p1 = data1, p2 = data2)
{
int retval = DllImport.WriteFile(boundHandle1.Handle, p1, DATA_SIZE, IntPtr.Zero, overlapped1);
if (retval == 0)
{
Assert.Equal(DllImport.ERROR_IO_PENDING, Marshal.GetLastWin32Error());
}
retval = DllImport.WriteFile(boundHandle2.Handle, p2, DATA_SIZE, IntPtr.Zero, overlapped2);
if (retval == 0)
{
Assert.Equal(DllImport.ERROR_IO_PENDING, Marshal.GetLastWin32Error());
}
// Wait for overlapped operations to complete
WaitHandle.WaitAll(new WaitHandle[] { result1.Event, result2.Event });
}
boundHandle1.FreeNativeOverlapped(overlapped1);
boundHandle2.FreeNativeOverlapped(overlapped2);
result1.Event.Reset();
result2.Event.Reset();
Assert.Equal(0, result1.ErrorCode);
Assert.Equal(0, result2.ErrorCode);
Assert.Equal(DATA_SIZE, result1.BytesWritten);
Assert.Equal(DATA_SIZE, result2.BytesWritten);
}
boundHandle1.Dispose();
boundHandle2.Dispose();
preAlloc1.Dispose();
preAlloc2.Dispose();
handle1.Dispose();
handle2.Dispose();
}