Inheritance: System.OperationCanceledException
Example #1
0
        private void CancelAllOperations()
        {
            if (_operation.TcsClose != null)
            {
                var exception = new WebSocketException(
                    WebSocketError.InvalidState,
                    SR.Format(
                        SR.net_WebSockets_InvalidState_ClosedOrAborted,
                        "System.Net.WebSockets.InternalClientWebSocket",
                        "Aborted"));

                _operation.TcsClose.TrySetException(exception);
            }

            if (_operation.TcsCloseOutput != null)
            {
                var exception = new WebSocketException(
                    WebSocketError.InvalidState,
                    SR.Format(
                        SR.net_WebSockets_InvalidState_ClosedOrAborted,
                        "System.Net.WebSockets.InternalClientWebSocket",
                        "Aborted"));

                _operation.TcsCloseOutput.TrySetException(exception);
            }

            if (_operation.TcsReceive != null)
            {
                var exception = new WebSocketException(
                    WebSocketError.InvalidState,
                    SR.Format(
                        SR.net_WebSockets_InvalidState_ClosedOrAborted,
                        "System.Net.WebSockets.InternalClientWebSocket",
                        "Aborted"));

                _operation.TcsReceive.TrySetException(exception);
            }

            if (_operation.TcsSend != null)
            {
                var exception = new OperationCanceledException();
                _operation.TcsSend.TrySetException(exception);
            }

            if (_operation.TcsUpgrade != null)
            {
                var exception = new WebSocketException(SR.net_webstatus_ConnectFailure);
                _operation.TcsUpgrade.TrySetException(exception);
            }
        }
        public void SendAsync_IfSendAsyncCancels_InControllerSelector_DoesNotCallExceptionServices()
        {
            // Arrange
            Exception expectedException = new OperationCanceledException();

            Mock<IExceptionLogger> exceptionLoggerMock = new Mock<IExceptionLogger>(MockBehavior.Strict);
            IExceptionLogger exceptionLogger = exceptionLoggerMock.Object;

            Mock<IExceptionHandler> exceptionHandlerMock = new Mock<IExceptionHandler>(MockBehavior.Strict);
            IExceptionHandler exceptionHandler = exceptionHandlerMock.Object;

            using (HttpRequestMessage expectedRequest = CreateRequestWithRouteData())
            using (HttpConfiguration configuration = CreateConfiguration())
            using (HttpMessageHandler product = CreateProductUnderTest(configuration, exceptionLogger,
                exceptionHandler))
            {
                configuration.Services.Replace(typeof(IHttpControllerSelector),
                    CreateThrowingControllerSelector(expectedException));

                CancellationToken cancellationToken = CreateCancellationToken();

                Task<HttpResponseMessage> task = product.SendAsync(expectedRequest, cancellationToken);

                // Act
                task.WaitUntilCompleted();

                // Assert
                Assert.Equal(TaskStatus.Canceled, task.Status);
            }
        }
Example #3
0
        /// <summary>
        /// Blocks the current thread until it can enter the <see cref="SemaphoreSlim"/>,
        /// using a 32-bit signed integer to measure the time interval,
        /// while observing a <see cref="T:System.Threading.CancellationToken"/>.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="Timeout.Infinite"/>(-1) to
        /// wait indefinitely.</param>
        /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to observe.</param>
        /// <returns>true if the current thread successfully entered the <see cref="SemaphoreSlim"/>; otherwise, false.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1,
        /// which represents an infinite time-out.</exception>
        /// <exception cref="System.OperationCanceledException"><paramref name="cancellationToken"/> was canceled.</exception>
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDispose();

            // Validate input
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
            }

            cancellationToken.ThrowIfCancellationRequested();

            // Perf: Check the stack timeout parameter before checking the volatile count
            if (millisecondsTimeout == 0 && m_currentCount == 0)
            {
                // Pessimistic fail fast, check volatile count outside lock (only when timeout is zero!)
                return(false);
            }

            uint startTime = 0;

            if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout > 0)
            {
                startTime = TimeoutHelper.GetTime();
            }

            bool        waitSuccessful = false;
            Task <bool> asyncWaitTask  = null;
            bool        lockTaken      = false;

            //Register for cancellation outside of the main lock.
            //NOTE: Register/deregister inside the lock can deadlock as different lock acquisition orders could
            //      occur for (1)this.m_lockObj and (2)cts.internalLock
            CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.InternalRegisterWithoutEC(s_cancellationTokenCanceledEventHandler, this);

            try
            {
                // Perf: first spin wait for the count to be positive, but only up to the first planned yield.
                //       This additional amount of spinwaiting in addition
                //       to Monitor.Enter()’s spinwaiting has shown measurable perf gains in test scenarios.
                //
                SpinWait spin = new SpinWait();
                while (m_currentCount == 0 && !spin.NextSpinWillYield)
                {
                    spin.SpinOnce();
                }
                // entering the lock and incrementing waiters must not suffer a thread-abort, else we cannot
                // clean up m_waitCount correctly, which may lead to deadlock due to non-woken waiters.
                try { }
                finally
                {
                    m_lock.Acquire();
                    lockTaken = true;
                    if (lockTaken)
                    {
                        m_waitCount++;
                    }
                }

                // If there are any async waiters, for fairness we'll get in line behind
                // then by translating our synchronous wait into an asynchronous one that we
                // then block on (once we've released the lock).
                if (m_asyncHead != null)
                {
                    Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't");
                    asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken);
                }
                // There are no async waiters, so we can proceed with normal synchronous waiting.
                else
                {
                    // If the count > 0 we are good to move on.
                    // If not, then wait if we were given allowed some wait duration

                    OperationCanceledException oce = null;

                    if (m_currentCount == 0)
                    {
                        if (millisecondsTimeout == 0)
                        {
                            return(false);
                        }

                        // Prepare for the main wait...
                        // wait until the count become greater than zero or the timeout is expired
                        try
                        {
                            waitSuccessful = WaitUntilCountOrTimeout(millisecondsTimeout, startTime, cancellationToken);
                        }
                        catch (OperationCanceledException e) { oce = e; }
                    }

                    // Now try to acquire.  We prioritize acquisition over cancellation/timeout so that we don't
                    // lose any counts when there are asynchronous waiters in the mix.  Asynchronous waiters
                    // defer to synchronous waiters in priority, which means that if it's possible an asynchronous
                    // waiter didn't get released because a synchronous waiter was present, we need to ensure
                    // that synchronous waiter succeeds so that they have a chance to release.
                    Debug.Assert(!waitSuccessful || m_currentCount > 0,
                                 "If the wait was successful, there should be count available.");
                    if (m_currentCount > 0)
                    {
                        waitSuccessful = true;
                        m_currentCount--;
                    }
                    else if (oce != null)
                    {
                        throw oce;
                    }

                    // Exposing wait handle which is lazily initialized if needed
                    if (m_waitHandle != null && m_currentCount == 0)
                    {
                        m_waitHandle.Reset();
                    }
                }
            }
            finally
            {
                // Release the lock
                if (lockTaken)
                {
                    m_waitCount--;
                    m_lock.Release();
                }

                // Unregister the cancellation callback.
                cancellationTokenRegistration.Dispose();
            }

            // If we had to fall back to asynchronous waiting, block on it
            // here now that we've released the lock, and return its
            // result when available.  Otherwise, this was a synchronous
            // wait, and whether we successfully acquired the semaphore is
            // stored in waitSuccessful.

            return((asyncWaitTask != null) ? asyncWaitTask.GetAwaiter().GetResult() : waitSuccessful);
        }
Example #4
0
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            this.CheckDispose();
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("totalMilliSeconds", (object)millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
            }
            cancellationToken.ThrowIfCancellationRequested();
            uint startTime = 0;

            if (millisecondsTimeout != -1 && millisecondsTimeout > 0)
            {
                startTime = TimeoutHelper.GetTime();
            }
            bool        flag      = false;
            Task <bool> task      = (Task <bool>)null;
            bool        lockTaken = false;
            CancellationTokenRegistration tokenRegistration = cancellationToken.InternalRegisterWithoutEC(SemaphoreSlim.s_cancellationTokenCanceledEventHandler, (object)this);

            try
            {
                SpinWait spinWait = new SpinWait();
                while (this.m_currentCount == 0 && !spinWait.NextSpinWillYield)
                {
                    spinWait.SpinOnce();
                }
                try
                {
                }
                finally
                {
                    Monitor.Enter(this.m_lockObj, ref lockTaken);
                    if (lockTaken)
                    {
                        this.m_waitCount = this.m_waitCount + 1;
                    }
                }
                if (this.m_asyncHead != null)
                {
                    task = this.WaitAsync(millisecondsTimeout, cancellationToken);
                }
                else
                {
                    OperationCanceledException canceledException = (OperationCanceledException)null;
                    if (this.m_currentCount == 0)
                    {
                        if (millisecondsTimeout == 0)
                        {
                            return(false);
                        }
                        try
                        {
                            flag = this.WaitUntilCountOrTimeout(millisecondsTimeout, startTime, cancellationToken);
                        }
                        catch (OperationCanceledException ex)
                        {
                            canceledException = ex;
                        }
                    }
                    if (this.m_currentCount > 0)
                    {
                        flag = true;
                        this.m_currentCount = this.m_currentCount - 1;
                    }
                    else if (canceledException != null)
                    {
                        throw canceledException;
                    }
                    if (this.m_waitHandle != null)
                    {
                        if (this.m_currentCount == 0)
                        {
                            this.m_waitHandle.Reset();
                        }
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    this.m_waitCount = this.m_waitCount - 1;
                    Monitor.Exit(this.m_lockObj);
                }
                tokenRegistration.Dispose();
            }
            if (task == null)
            {
                return(flag);
            }
            return(task.GetAwaiter().GetResult());
        }
        public void Invoke_IfStreamingCancels_DoesNotCallExceptionLogger()
        {
            // Arrange
            Exception expectedException = new OperationCanceledException();

            using (HttpContent content = CreateFaultingContent(expectedException))
            using (HttpResponseMessage expectedResponse = CreateResponse(content))
            using (HttpMessageHandler messageHandler = CreateStubMessageHandler(expectedResponse))
            {
                Mock<IExceptionLogger> mock = new Mock<IExceptionLogger>(MockBehavior.Strict);
                IExceptionLogger exceptionLogger = mock.Object;

                HttpMessageHandlerOptions options = CreateValidOptions(messageHandler);
                options.BufferPolicySelector = CreateBufferPolicySelector(bufferInput: false, bufferOutput: false);
                options.ExceptionLogger = exceptionLogger;

                using (HttpMessageHandlerAdapter product = CreateProductUnderTest(options))
                using (CancellationTokenSource tokenSource = CreateCancellationTokenSource())
                {
                    CancellationToken expectedCancellationToken = tokenSource.Token;
                    IOwinRequest owinRequest = CreateFakeOwinRequest(expectedCancellationToken);

                    IOwinResponse owinResponse = CreateFakeOwinResponse(Stream.Null);

                    IOwinContext context = CreateStubOwinContext(owinRequest, owinResponse);

                    // Act
                    Task task = product.Invoke(context);

                    // Assert
                    Assert.NotNull(task);
                    task.WaitUntilCompleted();
                    Assert.Equal(TaskStatus.Canceled, task.Status);
                }
            }
        }
        public void Invoke_IfBufferingErrorCancels_DoesNotCallExceptionLogger()
        {
            // Arrange
            Exception expectedOriginalException = CreateException();
            Exception expectedErrorException = new OperationCanceledException();

            using (HttpContent content = CreateFaultingContent(expectedOriginalException))
            using (HttpResponseMessage expectedOriginalResponse = CreateResponse(content))
            using (HttpMessageHandler messageHandler = CreateStubMessageHandler(expectedOriginalResponse))
            using (HttpContent errorContent = CreateFaultingContent(expectedErrorException))
            using (HttpResponseMessage expectedErrorResponse = CreateResponse(errorContent))
            using (CancellationTokenSource tokenSource = CreateCancellationTokenSource())
            {
                Mock<IExceptionLogger> mock = CreateStubExceptionLoggerMock();
                IExceptionLogger exceptionLogger = mock.Object;

                HttpMessageHandlerOptions options = CreateValidOptions(messageHandler);
                options.BufferPolicySelector = CreateBufferPolicySelector(bufferInput: false, bufferOutput: true);
                options.ExceptionLogger = exceptionLogger;
                options.ExceptionHandler = CreateExceptionHandler(new ResponseMessageResult(expectedErrorResponse));

                using (HttpMessageHandlerAdapter product = CreateProductUnderTest(options))
                {
                    CancellationToken expectedCancellationToken = tokenSource.Token;
                    IOwinRequest owinRequest = CreateFakeOwinRequest(expectedCancellationToken);
                    IOwinResponse owinResponse = CreateFakeOwinResponse(Stream.Null);

                    IOwinContext context = CreateStubOwinContext(owinRequest, owinResponse, isLocal: true);

                    // Act
                    Task task = product.Invoke(context);

                    // Assert
                    Assert.NotNull(task);
                    task.WaitUntilCompleted();
                    Assert.Equal(TaskStatus.Canceled, task.Status);

                    mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
                        c.ExceptionContext != null
                        && c.ExceptionContext.Exception == expectedOriginalException
                        && c.ExceptionContext.CatchBlock ==
                            OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferContent
                        && c.ExceptionContext.Request != null
                        && c.ExceptionContext.Response == expectedOriginalResponse),
                        expectedCancellationToken), Times.Once());

                    // This shouldn't be called for 'HttpMessageHandlerAdapterBufferError' because that's what's being
                    // cancelled.
                    mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
                        c.ExceptionContext != null
                        && c.ExceptionContext.Exception == expectedErrorException
                        && c.ExceptionContext.CatchBlock ==
                            OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferError
                        && c.ExceptionContext.Request != null
                        && c.ExceptionContext.Response == expectedErrorResponse),
                        expectedCancellationToken), Times.Never());
                }
            }
        }