diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs index a0af9a557f580..f8b01f140b75e 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs @@ -157,6 +157,7 @@ public WinHttpTransportContext TransportContext public long CurrentBytesRead { get; set; } private GCHandle _cachedReceivePinnedBuffer; + private GCHandle _cachedSendPinnedBuffer; public void PinReceiveBuffer(byte[] buffer) { @@ -171,6 +172,19 @@ public void PinReceiveBuffer(byte[] buffer) } } + public void PinSendBuffer(byte[] buffer) + { + if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer) + { + if (_cachedSendPinnedBuffer.IsAllocated) + { + _cachedSendPinnedBuffer.Free(); + } + + _cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); + } + } + #region IDisposable Members private void Dispose(bool disposing) { @@ -193,12 +207,18 @@ private void Dispose(bool disposing) { // This method only gets called when the WinHTTP request handle is fully closed and thus all // async operations are done. So, it is safe at this point to unpin the buffers and release - // the strong GCHandle for this object. + // the strong GCHandle for the pinned buffers. if (_cachedReceivePinnedBuffer.IsAllocated) { _cachedReceivePinnedBuffer.Free(); _cachedReceivePinnedBuffer = default(GCHandle); } + + if (_cachedSendPinnedBuffer.IsAllocated) + { + _cachedSendPinnedBuffer.Free(); + _cachedSendPinnedBuffer = default(GCHandle); + } #if DEBUG Interlocked.Increment(ref s_dbg_operationHandleFree); #endif diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs index ebbb43eaeedb4..64288c537fa67 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs @@ -24,8 +24,6 @@ internal sealed class WinHttpRequestStream : Stream private readonly SafeWinHttpHandle _requestHandle; private readonly WinHttpChunkMode _chunkedMode; - private GCHandle _cachedSendPinnedBuffer; - internal WinHttpRequestStream(WinHttpRequestState state, WinHttpChunkMode chunkedMode) { _state = state; @@ -182,15 +180,7 @@ internal async Task EndUploadAsync(CancellationToken token) protected override void Dispose(bool disposing) { - if (!_disposed) - { - _disposed = true; - if (_cachedSendPinnedBuffer.IsAllocated) - { - _cachedSendPinnedBuffer.Free(); - } - } - + _disposed = true; base.Dispose(disposing); } @@ -234,16 +224,7 @@ private Task InternalWriteDataAsync(byte[] buffer, int offset, int count, { Debug.Assert(count > 0); - if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer) - { - if (_cachedSendPinnedBuffer.IsAllocated) - { - _cachedSendPinnedBuffer.Free(); - } - - _cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); - } - + _state.PinSendBuffer(buffer); _state.TcsInternalWriteDataToRequestStream = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);