public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { this.EnsureOpened(); this.IncrementAsyncWriteCount(); Fx.Assert(this.writeState == null || this.writeState.Arguments == null || this.writeState.Arguments.Count <= 0, "All data has not been written yet."); if (onWriteCallback == null) { onWriteCallback = new AsyncEventArgsCallback(OnWriteCallback); onAsyncFlushComplete = new AsyncEventArgsCallback(OnAsyncFlushComplete); } if (this.writeState == null) { this.writeState = new WriteAsyncState(); this.writeArgs = new WriteAsyncArgs(); } else { // Since writeState!= null, check if the stream has an // exception as the async path has already been invoked. this.ThrowOnException(); } this.writeArgs.Set(buffer, offset, count, callback, state); this.writeState.Set(onWriteCallback, this.writeArgs, this); if (this.WriteAsync(this.writeState) == AsyncCompletionResult.Completed) { this.writeState.Complete(true); if (callback != null) { callback(this.writeState.CompletedSynchronouslyAsyncResult); } return(this.writeState.CompletedSynchronouslyAsyncResult); } return(this.writeState.PendingAsyncResult); }
AsyncCompletionResult WriteAsync(WriteAsyncState state) { Fx.Assert(state != null && state.Arguments != null, "Invalid WriteAsyncState parameter."); if (state.Arguments.Count == 0) { return(AsyncCompletionResult.Completed); } byte[] buffer = state.Arguments.Buffer; int offset = state.Arguments.Offset; int count = state.Arguments.Count; ByteBuffer currentBuffer = this.GetCurrentBuffer(); while (count > 0) { if (currentBuffer == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.GetString(SR.WriteAsyncWithoutFreeBuffer))); } int freeBytes = currentBuffer.FreeBytes; // space left in the CurrentBuffer if (freeBytes > 0) { if (freeBytes > count) { freeBytes = count; } currentBuffer.CopyData(buffer, offset, freeBytes); offset += freeBytes; count -= freeBytes; } if (currentBuffer.FreeBytes == 0) { this.DequeueAndFlush(currentBuffer, onAsyncFlushComplete); // We might need to increase the number of buffers available // if there is more data to be written or no buffer is available. if (count > 0 || this.buffers.Count == 0) { this.AdjustBufferSize(); } } //Update state for any pending writes. state.Arguments.Offset = offset; state.Arguments.Count = count; // We can complete synchronously only // if there a buffer available for writes. currentBuffer = this.GetCurrentBuffer(); if (currentBuffer == null) { if (this.buffers.TryUnlock()) { return(AsyncCompletionResult.Queued); } currentBuffer = this.GetCurrentBuffer(); } } return(AsyncCompletionResult.Completed); }
internal PooledAsyncResult(WriteAsyncState parentState, bool completedSynchronously) { this.writeState = parentState; this.completedSynchronously = completedSynchronously; }