private async Task ReadAndHandleRequestsAsync()

in src/StreamJsonRpc/JsonRpc.cs [2355:2415]


        private async Task ReadAndHandleRequestsAsync()
        {
            lock (this.syncObject)
            {
                // This block intentionally left blank.
                // It ensures that this thread will not receive messages before our caller (StartListening)
                // assigns the Task we return to a field before we go any further,
                // since our caller holds this lock until the field assignment completes.
                // See the StartListening_ShouldNotAllowIncomingMessageToRaceWithInvokeAsync test.
            }

            try
            {
                this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEvents.ListeningStarted, "Listening started.");

                while (!this.IsDisposed && !this.DisconnectedToken.IsCancellationRequested)
                {
                    JsonRpcMessage? protocolMessage = null;
                    try
                    {
                        protocolMessage = await this.MessageHandler.ReadAsync(this.DisconnectedToken).ConfigureAwait(false);
                        if (protocolMessage is null)
                        {
                            this.OnJsonRpcDisconnected(new JsonRpcDisconnectedEventArgs(Resources.ReachedEndOfStream, DisconnectedReason.RemotePartyTerminated));
                            return;
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        break;
                    }
                    catch (ObjectDisposedException)
                    {
                        break;
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch (Exception exception)
#pragma warning restore CA1031 // Do not catch general exception types
                    {
                        this.OnJsonRpcDisconnected(new JsonRpcDisconnectedEventArgs(
                            string.Format(CultureInfo.CurrentCulture, Resources.ReadingJsonRpcStreamFailed, exception.GetType().Name, exception.Message),
                            exception is JsonException ? DisconnectedReason.ParseError : DisconnectedReason.StreamError,
                            exception));
                        return;
                    }

                    this.HandleRpcAsync(protocolMessage).Forget(); // all exceptions are handled internally

                    // We must clear buffers before reading the next message.
                    // HandleRpcAsync must do whatever deserialization it requires before it yields.
                    (this.MessageHandler as IJsonRpcMessageBufferManager)?.DeserializationComplete(protocolMessage);
                }

                this.OnJsonRpcDisconnected(new JsonRpcDisconnectedEventArgs(Resources.StreamDisposed, DisconnectedReason.LocallyDisposed));
            }
            catch (Exception ex)
            {
                this.OnJsonRpcDisconnected(new JsonRpcDisconnectedEventArgs(ex.Message, DisconnectedReason.StreamError, ex));
                throw;
            }
        }