예제 #1
0
        public static Task <byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <byte[]>(cancellationToken));
            }

            // SequentialScan is a perf hint that requires extra sys-call on non-Windows OSes.
            FileOptions    options = FileOptions.Asynchronous | (OperatingSystem.IsWindows() ? FileOptions.SequentialScan : FileOptions.None);
            SafeFileHandle sfh     = OpenHandle(path, FileMode.Open, FileAccess.Read, FileShare.Read, options);

            long fileLength = 0L;

            if (sfh.CanSeek && (fileLength = sfh.GetFileLength()) > Array.MaxLength)
            {
                sfh.Dispose();
                return(Task.FromException <byte[]>(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.IO_FileTooLong2GB))));
            }

#if DEBUG
            fileLength = 0; // improve the test coverage for InternalReadAllBytesUnknownLengthAsync
#endif

            return(fileLength > 0 ?
                   InternalReadAllBytesAsync(sfh, (int)fileLength, cancellationToken) :
                   InternalReadAllBytesUnknownLengthAsync(sfh, cancellationToken));
        }
예제 #2
0
        protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            try
            {
                if (method != ConnectionCloseMethod.GracefulShutdown)
                {
                    // Dispose must be called first in order to cause a connection reset,
                    // as NetworkStream.Dispose() will call Shutdown(Both).
                    _socket.Dispose();
                }

                // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case:
                _stream?.Dispose();
            }
            catch (SocketException socketException)
            {
                return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(socketException)));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException(ex));
            }

            return(default);
예제 #3
0
        /// <inheritdoc/>
        public override ValueTask <ValueHttpRequest?> CreateNewRequestAsync(HttpPrimitiveVersion version, HttpVersionPolicy versionPolicy, CancellationToken cancellationToken = default)
        {
            if (_writeBuffer.ActiveLength != 0 || _responseContentBytesRemaining != 0)
            {
                return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception("Unable to create request stream with a request already pending."))));
            }

            if (version.Major != 1)
            {
                if (versionPolicy == HttpVersionPolicy.RequestVersionOrLower)
                {
                    version = HttpPrimitiveVersion.Version11;
                }
                return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception($"Unable to create request for HTTP/{version.Major}.{version.Minor} with a {nameof(Http1Connection)}."))));
            }

            _writeState                = WriteState.Unstarted;
            _requestIsChunked          = true;
            _responseHasContentLength  = false;
            _responseIsChunked         = false;
            _readingFirstResponseChunk = false;
            _readFunc = s_ReadResponse;

            if (Interlocked.Exchange(ref _request, null) is Http1Request request)
            {
                request.Init(this, version);
            }
            else
            {
                request = new Http1Request(this, version);
            }

            return(new ValueTask <ValueHttpRequest?>(request.GetValueRequest()));
        }
예제 #4
0
 private void CancelWaiter(CancellationToken cancellationToken)
 {
     if (Interlocked.Exchange(ref _hasWaiter, 0) == 1)
     {
         _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(cancellationToken)));
     }
 }
예제 #5
0
        private static uint HandleEventShutdownComplete(State state, ref ConnectionEvent connectionEvent)
        {
            // This is the final event on the connection, so free the GCHandle used by the event callback.
            state.StateGCHandle.Free();

            state.Connection = null;

            state.ShutdownTcs.SetResult(MsQuicStatusCodes.Success);

            // Stop accepting new streams.
            state.AcceptQueue.Writer.TryComplete();

            // Stop notifying about available streams.
            TaskCompletionSource?unidirectionalTcs = null;
            TaskCompletionSource?bidirectionalTcs  = null;

            lock (state)
            {
                unidirectionalTcs = state.NewUnidirectionalStreamsAvailable;
                bidirectionalTcs  = state.NewBidirectionalStreamsAvailable;
                state.NewUnidirectionalStreamsAvailable = null;
                state.NewBidirectionalStreamsAvailable  = null;
            }

            if (unidirectionalTcs is not null)
            {
                unidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException()));
            }
            if (bidirectionalTcs is not null)
            {
                bidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException()));
            }
            return(MsQuicStatusCodes.Success);
        }
예제 #6
0
        protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            try
            {
                if (method != ConnectionCloseMethod.GracefulShutdown)
                {
                    // Dispose must be called first in order to cause a connection reset,
                    // as NetworkStream.Dispose() will call Shutdown(Both).
                    _stream.Socket.Dispose();
                }

                _stream.Dispose();
            }
            catch (SocketException socketException)
            {
                return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException))));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException(ex));
            }

            return(default);
            public void OnCompleted()
            {
                if (_gatheredSegments != null)
                {
                    _gatheredSegments.Clear();

                    if (_pooledArrays != null)
                    {
                        foreach (byte[] buffer in _pooledArrays)
                        {
                            ArrayPool <byte> .Shared.Return(buffer);
                        }
                        _pooledArrays.Clear();
                    }
                }

                if (SocketError == SocketError.Success)
                {
                    SetResult(0);
                }
                else
                {
                    SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException($"{nameof(WriteAsync)} failed. See InnerException for more details.", new SocketException((int)SocketError))));
                }
            }
예제 #8
0
        /// <summary>Gets a SocketException or an IOException wrapping a SocketException for the specified error.</summary>
        private static Exception GetException(SocketError error, bool wrapExceptionsInIOExceptions = false)
        {
            Exception e = ExceptionDispatchInfo.SetCurrentStackTrace(new SocketException((int)error));

            return(wrapExceptionsInIOExceptions ?
                   new IOException(SR.Format(SR.net_io_readwritefailure, e.Message), e) :
                   e);
        }
예제 #9
0
 private void CancelWaiter()
 {
     if (Interlocked.Exchange(ref _hasWaiter, 0) == 1)
     {
         Debug.Assert(_waitSourceCancellationToken != default);
         _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(_waitSourceCancellationToken)));
     }
 }
예제 #10
0
        /// <inheritdoc/>
        public sealed override ValueTask <Connection> ConnectAsync(EndPoint?endPoint, IConnectionProperties?options = null, CancellationToken cancellationToken = default)
        {
            if (options == null || !options.TryGet(out DnsEndPointWithProperties? httpOptions))
            {
                return(ValueTask.FromException <Connection>(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException($"{nameof(SocketsHttpConnectionFactory)} requires a {nameof(DnsEndPointWithProperties)} property."))));
            }

            return(EstablishConnectionAsync(httpOptions !.InitialRequest, endPoint, options, cancellationToken));
        }
예제 #11
0
            private void CancelWaiter()
            {
                if (Interlocked.Exchange(ref _hasWaiter, 0) == 1)
                {
                    Debug.Assert(_waitSourceCancellationToken != default);
#if NET5_0_OR_GREATER // API introduced in .NET 5
                    _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(_waitSourceCancellationToken)));
#endif
                }
            }
        private uint HandleEventShutdownInitiatedByTransport(ref ConnectionEvent connectionEvent)
        {
            if (!_connected)
            {
                uint      hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
                Exception ex      = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport.");
                _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
            }

            return(MsQuicStatusCodes.Success);
        }
예제 #13
0
        private uint HandleEventShutdownInitiatedByTransport(ref ConnectionEvent connectionEvent)
        {
            if (!_connected)
            {
                _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException("Connection has been shutdown.")));
            }

            _acceptQueue.Writer.Complete();

            return(MsQuicStatusCodes.Success);
        }
예제 #14
0
            protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
            {
                if (_originalPipe == null)
                {
                    return;
                }

                Exception?inputException, outputException;

                if (method == ConnectionCloseMethod.GracefulShutdown)
                {
                    // Flush happens implicitly from CompleteAsync(null), so only flush here if we need cancellation.
                    if (cancellationToken.CanBeCanceled)
                    {
                        FlushResult r = await _originalPipe.Output.FlushAsync(cancellationToken).ConfigureAwait(false);

                        if (r.IsCanceled)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                    }

                    inputException  = null;
                    outputException = null;
                }
                else
                {
                    inputException  = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection)));
                    outputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection)));
                }

                await _originalPipe.Input.CompleteAsync(inputException).ConfigureAwait(false);

                await _originalPipe.Output.CompleteAsync(outputException).ConfigureAwait(false);

                if (!_leaveOpen)
                {
                    switch (_originalPipe)
                    {
                    case IAsyncDisposable d:
                        await d.DisposeAsync().ConfigureAwait(false);

                        break;

                    case IDisposable d:
                        d.Dispose();
                        break;
                    }
                }

                _originalPipe = null;
            }
예제 #15
0
        private static uint HandleEventShutdownInitiatedByTransport(State state, ref ConnectionEvent connectionEvent)
        {
            if (!state.Connected)
            {
                Debug.Assert(state.Connection != null);
                state.Connection = null;

                uint      hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
                Exception ex      = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport.");
                state.ConnectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
            }

            state.AcceptQueue.Writer.Complete();
            return(MsQuicStatusCodes.Success);
        }
예제 #16
0
        private static uint HandleEventShutdownComplete(State state, ref ConnectionEvent connectionEvent)
        {
            // This is the final event on the connection, so free the GCHandle used by the event callback.
            state.StateGCHandle.Free();

            if (state.ListenerState != null)
            {
                // This is inbound connection that never got connected - becasue of TLS validation or some other reason.
                // Remove connection from pending queue and dispose it.
                if (state.ListenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out MsQuicConnection? connection))
                {
                    connection.Dispose();
                }

                state.ListenerState = null;
            }

            state.Connection = null;

            state.ShutdownTcs.SetResult(MsQuicStatusCodes.Success);

            // Stop accepting new streams.
            state.AcceptQueue.Writer.TryComplete();

            // Stop notifying about available streams.
            TaskCompletionSource?unidirectionalTcs = null;
            TaskCompletionSource?bidirectionalTcs  = null;

            lock (state)
            {
                unidirectionalTcs = state.NewUnidirectionalStreamsAvailable;
                bidirectionalTcs  = state.NewBidirectionalStreamsAvailable;
                state.NewUnidirectionalStreamsAvailable = null;
                state.NewBidirectionalStreamsAvailable  = null;
            }

            if (unidirectionalTcs is not null)
            {
                unidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException()));
            }
            if (bidirectionalTcs is not null)
            {
                bidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException()));
            }

            return(MsQuicStatusCodes.Success);
        }
예제 #17
0
            public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(ValueTask.FromCanceled(cancellationToken));
                }

                HttpConnection?connection = _connection;

                if (connection == null)
                {
                    return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.ObjectDisposed_StreamClosed))));
                }

                if (buffer.Length == 0)
                {
                    return(default);
        public static void SetCurrentStackTrace_Invalid_Throws()
        {
            Exception e;

            // Null argument
            e = null;
            AssertExtensions.Throws <ArgumentNullException>("source", () => ExceptionDispatchInfo.SetCurrentStackTrace(e));

            // Previously set current stack
            e = new Exception();
            ExceptionDispatchInfo.SetCurrentStackTrace(e);
            Assert.Throws <InvalidOperationException>(() => ExceptionDispatchInfo.SetCurrentStackTrace(e));

            // Previously thrown
            e = new Exception();
            try { throw e; } catch { }
            Assert.Throws <InvalidOperationException>(() => ExceptionDispatchInfo.SetCurrentStackTrace(e));
        }
예제 #19
0
        private static int HandleEventShutdownInitiatedByTransport(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
        {
            if (!state.Connected && state.ConnectTcs != null)
            {
                Debug.Assert(state.Connection != null);
                state.Connection = null;

                Exception ex = new MsQuicException(connectionEvent.SHUTDOWN_INITIATED_BY_TRANSPORT.Status, "Connection has been shutdown by transport");
                state.ConnectTcs !.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
                state.ConnectTcs = null;
            }

            // To throw QuicConnectionAbortedException (instead of QuicOperationAbortedException) out of AcceptStreamAsync() since
            // it wasn't our side who shutdown the connection.
            // We should rather keep the Status and propagate it either in a different exception or as a different field of QuicConnectionAbortedException.
            // See: https://github.com/dotnet/runtime/issues/60133
            state.AbortErrorCode = 0;
            state.AcceptQueue.Writer.TryComplete();
            return(QUIC_STATUS_SUCCESS);
        }
예제 #20
0
        private void RegisterCancellation(CancellationToken cancellationToken)
        {
            _registration = cancellationToken.UnsafeRegister(s =>
            {
                CancelableCreditWaiter thisRef = (CancelableCreditWaiter)s !;
                lock (thisRef._syncObj)
                {
                    if (thisRef.IsPending)
                    {
                        thisRef._registration = default; // benign race with setting in the ctor
                        thisRef._source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(thisRef._registration.Token)));

                        // We don't remove it from the list as we lack a prev pointer that would enable us to do so correctly,
                        // and it's not worth adding a prev pointer for the rare case of cancellation.  We instead just
                        // check when completing a waiter whether it's already been canceled.  As such, we also do not
                        // dispose it here.
                    }
                }
            }, this);
        }
예제 #21
0
        public void Dispose()
        {
            lock (SyncObject)
            {
                if (_disposed)
                {
                    return;
                }

                _disposed = true;

                if (_waiters != null)
                {
                    while (_waiters.TryDequeue(out Waiter waiter))
                    {
                        waiter.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(CreateObjectDisposedException(forActiveWaiter: true)));
                    }
                }
            }
        }
예제 #22
0
        private static uint HandleEventShutdownInitiatedByTransport(State state, ref ConnectionEvent connectionEvent)
        {
            if (!state.Connected && state.ConnectTcs != null)
            {
                Debug.Assert(state.Connection != null);
                state.Connection = null;

                uint      hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
                Exception ex      = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport.");
                state.ConnectTcs !.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
                state.ConnectTcs = null;
            }

            // To throw QuicConnectionAbortedException (instead of QuicOperationAbortedException) out of AcceptStreamAsync() since
            // it wasn't our side who shutdown the connection.
            // We should rather keep the Status and propagate it either in a different exception or as a different field of QuicConnectionAbortedException.
            // See: https://github.com/dotnet/runtime/issues/60133
            state.AbortErrorCode = 0;
            state.AcceptQueue.Writer.TryComplete();
            return(MsQuicStatusCodes.Success);
        }
예제 #23
0
파일: Program.cs 프로젝트: athinboy/mystudy
        static void Method3()
        {
            try
            {
                throw new Exception("Exception3");
            }
            catch (Exception ex)
            {
                logger.Error(ex);

                ExceptionDispatchInfo.SetCurrentStackTrace(ex);

                StackTrace   stackTrace = new StackTrace(ex);
                StackFrame[] frames     = stackTrace.GetFrames();
                for (int i = 0; i < frames.Length; i++)
                {
                    StackFrame sf = frames[i];
                }

                stackTrace = new StackTrace(true);
                frames     = stackTrace.GetFrames();
                for (int i = 0; i < frames.Length; i++)
                {
                    StackFrame sf = frames[i];
                }



                if (Debugger.IsAttached)
                {
                    Debug.WriteLine(ex);
                }
                Console.WriteLine(ex);


                Console.WriteLine(ex.ToString());
            }

            throw new Exception("Exception");
        }
예제 #24
0
            protected override void OnCompleted(SocketAsyncEventArgs _)
            {
                switch (SocketError)
                {
                case SocketError.Success:
                    Builder.SetResult();
                    break;

                case SocketError.OperationAborted:
                case SocketError.ConnectionAborted:
                    if (CancellationToken.IsCancellationRequested)
                    {
                        Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(CancellationHelper.CreateOperationCanceledException(null, CancellationToken)));
                        break;
                    }
                    goto default;

                default:
                    Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new SocketException((int)SocketError)));
                    break;
                }
            }
예제 #25
0
        public static Task <byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <byte[]>(cancellationToken));
            }

            var fs = new FileStream(
                path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1, // bufferSize == 1 used to avoid unnecessary buffer in FileStream
                FileOptions.Asynchronous | FileOptions.SequentialScan);

            bool returningInternalTask = false;

            try
            {
                long fileLength = fs.Length;
                if (fileLength > int.MaxValue)
                {
                    var e = new IOException(SR.IO_FileTooLong2GB);
#if !MS_IO_REDIST
                    ExceptionDispatchInfo.SetCurrentStackTrace(e);
#endif
                    return(Task.FromException <byte[]>(e));
                }

                returningInternalTask = true;
                return(fileLength > 0 ?
                       InternalReadAllBytesAsync(fs, (int)fileLength, cancellationToken) :
                       InternalReadAllBytesUnknownLengthAsync(fs, cancellationToken));
            }
            finally
            {
                if (!returningInternalTask)
                {
                    fs.Dispose();
                }
            }
        }
예제 #26
0
 protected override void HandleUnexpectedCancellation() =>
 TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(Error.GetOperationAborted()));
 /// <inheritdoc/>
 public override ValueTask <ConnectionListener> ListenAsync(EndPoint?endPoint, IConnectionProperties?options = null, CancellationToken cancellationToken = default)
 {
     return(ValueTask.FromException <ConnectionListener>(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException($"{nameof(HttpTunnelConnectionFactory)} does not support listening."))));
 }
예제 #28
0
        private ValueTask WriteSingleChunk <TIOAdapter>(TIOAdapter writeAdapter, ReadOnlyMemory <byte> buffer)
            where TIOAdapter : struct, ISslIOAdapter
        {
            // Request a write IO slot.
            Task ioSlot = writeAdapter.WriteLockAsync();

            if (!ioSlot.IsCompletedSuccessfully)
            {
                // Operation is async and has been queued, return.
                return(WaitForWriteIOSlot(writeAdapter, ioSlot, buffer));
            }

            byte[] rentedBuffer = ArrayPool <byte> .Shared.Rent(buffer.Length + FrameOverhead);

            byte[] outBuffer = rentedBuffer;

            SecurityStatusPal status = EncryptData(buffer, ref outBuffer, out int encryptedBytes);

            if (status.ErrorCode != SecurityStatusPalErrorCode.OK)
            {
                // Re-handshake status is not supported.
                ArrayPool <byte> .Shared.Return(rentedBuffer);

                ProtocolToken message = new ProtocolToken(null, status);
                return(new ValueTask(Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.net_io_encrypt, message.GetException())))));
            }

            ValueTask t = writeAdapter.WriteAsync(outBuffer, 0, encryptedBytes);

            if (t.IsCompletedSuccessfully)
            {
                ArrayPool <byte> .Shared.Return(rentedBuffer);

                FinishWrite();
                return(t);
            }
            else
            {
                return(CompleteAsync(t, rentedBuffer));
            }

            async ValueTask WaitForWriteIOSlot(TIOAdapter wAdapter, Task lockTask, ReadOnlyMemory <byte> buff)
            {
                await lockTask.ConfigureAwait(false);

                await WriteSingleChunk(wAdapter, buff).ConfigureAwait(false);
            }

            async ValueTask CompleteAsync(ValueTask writeTask, byte[] bufferToReturn)
            {
                try
                {
                    await writeTask.ConfigureAwait(false);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(bufferToReturn);

                    FinishWrite();
                }
            }
        }
예제 #29
0
        protected internal sealed override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                                                CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest);
            }

            // ProcessRequest() and ProcessResponse() are supposed to be fast, so we call ProcessRequest() on the same
            // thread SendAsync() was invoked to avoid context switches. However, if ProcessRequest() throws, we have
            // to catch the exception since the caller doesn't expect exceptions when calling SendAsync(): The
            // expectation is that the returned task will get faulted on errors, but the async call to SendAsync()
            // should complete.
            var tcs = new SendState(this, cancellationToken);

            try
            {
                HttpRequestMessage         newRequestMessage = ProcessRequest(request, cancellationToken);
                Task <HttpResponseMessage> sendAsyncTask     = base.SendAsync(newRequestMessage, cancellationToken);

                // We schedule a continuation task once the inner handler completes in order to trigger the response
                // processing method. ProcessResponse() is only called if the task wasn't canceled before.
                sendAsyncTask.ContinueWithStandard(tcs, (task, state) =>
                {
                    var sendState = (SendState)state;
                    MessageProcessingHandler self = sendState._handler;
                    CancellationToken token       = sendState._token;

                    if (task.IsFaulted)
                    {
                        sendState.TrySetException(task.Exception.GetBaseException());
                        return;
                    }

                    if (task.IsCanceled)
                    {
                        sendState.TrySetCanceled();
                        return;
                    }

                    if (task.Result == null)
                    {
                        sendState.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(new InvalidOperationException(SR.net_http_handler_noresponse)));
                        return;
                    }

                    try
                    {
                        HttpResponseMessage responseMessage = self.ProcessResponse(task.Result, token);
                        sendState.TrySetResult(responseMessage);
                    }
                    catch (OperationCanceledException e)
                    {
                        // If ProcessResponse() throws an OperationCanceledException check whether it is related to
                        // the cancellation token we received from the user. If so, cancel the Task.
                        HandleCanceledOperations(token, sendState, e);
                    }
                    catch (Exception e)
                    {
                        sendState.TrySetException(e);
                    }
                    // We don't pass the cancellation token to the continuation task, since we want to get called even
                    // if the operation was canceled: We'll set the Task returned to the user to canceled. Passing the
                    // cancellation token here would result in the continuation task to not be called at all. I.e. we
                    // would never complete the task returned to the caller of SendAsync().
                });
            }
            catch (OperationCanceledException e)
            {
                HandleCanceledOperations(cancellationToken, tcs, e);
            }
            catch (Exception e)
            {
                tcs.TrySetException(e);
            }

            return(tcs.Task);
        }
 private static void ABCDEFGHIJKLMNOPQRSTUVWXYZ(Exception e)
 {
     Assert.Same(e, ExceptionDispatchInfo.SetCurrentStackTrace(e));
 }