private Task WriteAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var completionSource = new ReadWriteCompletionSource(this, buffer, cancellationToken, isWrite: true);
int errorCode = 0;
// Queue an async WriteFile operation and pass in a packed overlapped
int r;
unsafe
{
r = WriteFileNative(_handle, buffer, offset, count, completionSource.Overlapped, out errorCode);
}
// WriteFile, the OS version, will return 0 on failure, but this WriteFileNative
// wrapper returns -1. This will return the following:
// - On error, r==-1.
// - On async requests that are still pending, r==-1 w/ hr==ERROR_IO_PENDING
// - On async requests that completed sequentially, r==0
//
// You will NEVER RELIABLY be able to get the number of buffer written back from this
// call when using overlapped structures! You must not pass in a non-null
// lpNumBytesWritten to WriteFile when using overlapped structures! This is by design
// NT behavior.
if (r == -1 && errorCode != Interop.Errors.ERROR_IO_PENDING)
{
completionSource.ReleaseResources();
throw WinIOError(errorCode);
}
completionSource.RegisterForCancellation();
return completionSource.Task;
}