Ejemplo n.º 1
0
        /// <summary>
        /// Clean up can be called by:
        /// 1. The user. AsyncUnaryCall.Dispose et al will call this on Dispose
        /// 2. <see cref="ValidateHeaders"/> will call dispose if errors fail validation
        /// 3. <see cref="FinishResponseAndCleanUp"/> will call dispose
        /// </summary>
        private void Cleanup(Status status)
        {
            if (!ResponseFinished)
            {
                // If the response is not finished then cancel any pending actions:
                // 1. Call HttpClient.SendAsync
                // 2. Response Stream.ReadAsync
                // 3. Client stream
                //    - Getting the Stream from the Request.HttpContent
                //    - Holding the Request.HttpContent.SerializeToStream open
                //    - Writing to the client stream
                CancelCall(status);
            }
            else
            {
                _callTcs.TrySetResult(status);

                ClientStreamWriter?.WriteStreamTcs.TrySetCanceled();
                ClientStreamWriter?.CompleteTcs.TrySetCanceled();
                ClientStreamReader?.HttpResponseTcs.TrySetCanceled();
            }

            _ctsRegistration?.Dispose();
            _deadlineTimer?.Dispose();
            HttpResponse?.Dispose();
            ClientStreamReader?.Dispose();
            ClientStreamWriter?.Dispose();

            // To avoid racing with Dispose, skip disposing the call CTS.
            // This avoid Dispose potentially calling cancel on a disposed CTS.
            // The call CTS is not exposed externally and all dependent registrations
            // are cleaned up.
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Dispose can be called by:
        /// 1. The user. AsyncUnaryCall.Dispose et al will call this Dispose
        /// 2. <see cref="ValidateHeaders"/> will call dispose if errors fail validation
        /// 3. <see cref="FinishResponse"/> will call dispose
        /// </summary>
        public void Dispose()
        {
            if (!Disposed)
            {
                Disposed = true;

                if (!ResponseFinished)
                {
                    // If the response is not finished then cancel any pending actions:
                    // 1. Call HttpClient.SendAsync
                    // 2. Response Stream.ReadAsync
                    // 3. Client stream
                    //    - Getting the Stream from the Request.HttpContent
                    //    - Holding the Request.HttpContent.SerializeToStream open
                    //    - Writing to the client stream
                    _callCts.Cancel();
                }

                _ctsRegistration?.Dispose();
                _writerCtsRegistration?.Dispose();
                _deadlineTimer?.Dispose();
                HttpResponse?.Dispose();
                ClientStreamReader?.Dispose();
                ClientStreamWriter?.Dispose();

                // To avoid racing with Dispose, skip disposing the call CTS
                // This avoid Dispose potentially calling cancel on a disposed CTS
                // The call CTS is not exposed externally and all dependent registrations
                // are cleaned up
            }
        }
Ejemplo n.º 3
0
        private void DisposeCore()
        {
            if (!Disposed)
            {
                // Locking on the call because:
                // 1. Its not exposed publically
                // 2. Nothing else locks on call
                // 3. We want to avoid allocating a private lock object
                lock (this)
                {
                    if (!Disposed)
                    {
                        Disposed = true;

                        if (!ResponseFinished)
                        {
                            // If the response is not finished then cancel any pending actions:
                            // 1. Call HttpClient.SendAsync
                            // 2. Response Stream.ReadAsync
                            // 3. Client stream
                            //    - Getting the Stream from the Request.HttpContent
                            //    - Holding the Request.HttpContent.SerializeToStream open
                            //    - Writing to the client stream
                            CancelCall();
                        }
                        else
                        {
                            _writeStreamTcs?.TrySetCanceled();
                            _writeCompleteTcs?.TrySetCanceled();
                        }

                        // If response has successfully finished then the status will come from the trailers
                        // If it didn't finish then complete with a Cancelled status
                        _callTcs.TrySetResult(StatusCode.Cancelled);

                        _ctsRegistration?.Dispose();
                        _deadlineTimer?.Dispose();
                        HttpResponse?.Dispose();
                        ClientStreamReader?.Dispose();
                        ClientStreamWriter?.Dispose();

                        // To avoid racing with Dispose, skip disposing the call CTS
                        // This avoid Dispose potentially calling cancel on a disposed CTS
                        // The call CTS is not exposed externally and all dependent registrations
                        // are cleaned up
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Clean up can be called by:
        /// 1. The user. AsyncUnaryCall.Dispose et al will call this on Dispose
        /// 2. <see cref="GrpcCall.ValidateHeaders"/> will call dispose if errors fail validation
        /// 3. <see cref="FinishResponseAndCleanUp"/> will call dispose
        /// </summary>
        private void Cleanup(Status status)
        {
            if (!ResponseFinished)
            {
                // If the response is not finished then cancel any pending actions:
                // 1. Call HttpClient.SendAsync
                // 2. Response Stream.ReadAsync
                // 3. Client stream
                //    - Getting the Stream from the Request.HttpContent
                //    - Holding the Request.HttpContent.SerializeToStream open
                //    - Writing to the client stream
                CancelCall(status);
            }
            else
            {
                _callTcs.TrySetResult(status);

                ClientStreamWriter?.WriteStreamTcs.TrySetCanceled();
                ClientStreamWriter?.CompleteTcs.TrySetCanceled();
                ClientStreamReader?.HttpResponseTcs.TrySetCanceled();
            }

            Channel.FinishActiveCall(this);

            _ctsRegistration?.Dispose();

            if (_deadlineTimer != null)
            {
                lock (this)
                {
                    // Timer callback can call Timer.Change so dispose deadline timer in a lock
                    // and set to null to indicate to the callback that it has been disposed.
                    _deadlineTimer?.Dispose();
                    _deadlineTimer = null;
                }
            }

            HttpResponse?.Dispose();
            ClientStreamReader?.Dispose();
            ClientStreamWriter?.Dispose();

            // To avoid racing with Dispose, skip disposing the call CTS.
            // This avoid Dispose potentially calling cancel on a disposed CTS.
            // The call CTS is not exposed externally and all dependent registrations
            // are cleaned up.
        }