Exemple #1
0
        private void CancelCall(Status status)
        {
            // Set overall call status first. Status can be used in throw RpcException from cancellation.
            // If response has successfully finished then the status will come from the trailers.
            // If it didn't finish then complete with a status.
            _callTcs.TrySetResult(status);

            // Checking if cancellation has already happened isn't threadsafe
            // but there is no adverse effect other than an extra log message
            if (!_callCts.IsCancellationRequested)
            {
                GrpcCallLog.CanceledCall(Logger);

                // Cancel in-progress HttpClient.SendAsync and Stream.ReadAsync tasks.
                // Cancel will send RST_STREAM if HttpClient.SendAsync isn't complete.
                // Cancellation will also cause reader/writer to throw if used afterwards.
                _callCts.Cancel();

                // Cancellation token won't send RST_STREAM if HttpClient.SendAsync is complete.
                // Dispose HttpResponseMessage to send RST_STREAM to server for in-progress calls.
                HttpResponse?.Dispose();

                // Canceling call will cancel pending writes to the stream
                ClientStreamWriter?.WriteStreamTcs.TrySetCanceled();
                ClientStreamWriter?.CompleteTcs.TrySetCanceled();
                ClientStreamReader?.HttpResponseTcs.TrySetCanceled();
            }
        }