コード例 #1
0
        private Task WriteAsyncCore(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken)
        {
            var completionSource = new ReadWriteCompletionSource(this, buffer, isWrite: true);
            int errorCode        = 0;

            // Queue an async WriteFile operation and pass in a packed overlapped
            int r;

            unsafe
            {
                r = WriteFileNative(_handle, buffer.Span, 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(cancellationToken);
            return(completionSource.Task);
        }
コード例 #2
0
        private Task <int> ReadAsyncCore(Memory <byte> buffer, CancellationToken cancellationToken)
        {
            var completionSource = new ReadWriteCompletionSource(this, buffer, isWrite: false);

            // Queue an async ReadFile operation and pass in a packed overlapped
            int errorCode = 0;
            int r;

            unsafe
            {
                r = ReadFileNative(_handle, buffer.Span, completionSource.Overlapped, out errorCode);
            }

            // ReadFile, the OS version, will return 0 on failure, but this ReadFileNative 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 read back from this call
            // when using overlapped structures!  You must not pass in a non-null lpNumBytesRead to
            // ReadFile when using overlapped structures!  This is by design NT behavior.
            if (r == -1)
            {
                switch (errorCode)
                {
                // One side has closed its handle or server disconnected.
                // Set the state to Broken and do some cleanup work
                case Interop.Errors.ERROR_BROKEN_PIPE:
                case Interop.Errors.ERROR_PIPE_NOT_CONNECTED:
                    State = PipeState.Broken;

                    unsafe
                    {
                        // Clear the overlapped status bit for this special case. Failure to do so looks
                        // like we are freeing a pending overlapped.
                        completionSource.Overlapped->InternalLow = IntPtr.Zero;
                    }

                    completionSource.ReleaseResources();
                    UpdateMessageCompletion(true);
                    return(s_zeroTask);

                case Interop.Errors.ERROR_IO_PENDING:
                    break;

                default:
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }
            }

            completionSource.RegisterForCancellation(cancellationToken);
            return(completionSource.Task);
        }
コード例 #3
0
        private Task WriteAsyncCorePrivate(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            Debug.Assert(_handle != null, "_handle is null");
            Debug.Assert(!_handle.IsClosed, "_handle is closed");
            Debug.Assert(CanWrite, "can't write");
            Debug.Assert(buffer != null, "buffer == null");
            Debug.Assert(_isAsync, "WriteAsyncCorePrivate doesn't work on synchronous file streams!");
            Debug.Assert(offset >= 0, "offset is negative");
            Debug.Assert(count >= 0, "count is negative");

            if (buffer.Length == 0)
            {
                return(Task.CompletedTask);
            }
            else
            {
                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.mincore.Errors.ERROR_IO_PENDING)
                {
                    completionSource.ReleaseResources();
                    throw WinIOError(errorCode);
                }

                completionSource.RegisterForCancellation();
                return(completionSource.Task);
            }
        }