C# Grpc System.InvalidOperationException: 'Cannot write message after request is complete.'

Viewed 2124

At runtime I get the following error:

System.InvalidOperationException: 'Cannot write message after request is complete.'

I'm using Grpc and reactive X to get data.

public class SensorService: Protos.Vehicule.VehiculeBase
{

    private readonly ILogger<SensorService> _logger;
    private DataProvider _dataProvider;
    private CarSim.Vehicule _vehicule;

    public SensorService(ILogger<SensorService> logger)
    {
      
        _dataProvider = new DataProvider(new CarSim.Vehicule());
        _vehicule = _dataProvider.getVehicule();
        _logger = logger;
        _dataProvider.Start();
    }

    public System.IObserver<CarSim.Vehicule> GetData { get; private set; }

    public override async Task Status(All request, IServerStreamWriter<StatusVehicule> responseStream, ServerCallContext context)
    {  
        
        while (!context.CancellationToken.IsCancellationRequested)
        {

             _vehicule.VehiculeChangedState.Subscribe(onNext: new Action<CarSim.Vehicule>(async (t) =>
            {
                await responseStream.WriteAsync(new StatusVehicule()
                 {
                     Camera = t.Camera,
                     FuelLevel = t.FuelLevel,
                     GunStatus = true,
                     Light = t.Light,
                     OilLevel = t.OilLevel,
                     Peed = t.Speed,
                    
                     Tempature = t.Tempature
                 }                

                    );
                 
             ; }));
         
        }
    }

    
}

enter image description here

3 Answers

This is likely not a bug. The exception means that you're trying to send a response after the RPC has actually finished. Usually this happens when the RPC deadline is exceeded (at which point the RPC is automatically cancelled) or when it was cancelled by the client. Both of these situations can happen at any time (from the server side handler's perspective) and they are basically an inherent race condition (the RPC could have been cancelled just before you decide to send the response).

The exception is just gRPC's way of informing you that the response could not be sent (and there is really no way to send a response AFTER the RPC has finished).

You must register SensorService in your gRpc Server code: like this: app.UseEndpoints(endpoints => { endpoints.MapGrpcService<SensorService >(); .....

I have found a solution that works. But i still have the same error.

   public override async Task Status(All request, IServerStreamWriter<StatusVehicule> responseStream, ServerCallContext context){

        try
        {
            var eventLoop = new EventLoopScheduler();
            await _vehicule.VehiculeChangedState.ObserveOn(eventLoop).ForEachAsync<CarSim.Vehicule>(t =>
                {
                    try
                    {
                        responseStream.WriteAsync(new StatusVehicule()
                            {
                                Camera = t.Camera,
                                FuelLevel = t.FuelLevel,
                                GunStatus = true,
                                Light = t.Light,
                                OilLevel = t.OilLevel,
                                Peed = t.Speed,
                                Status = t.GetState().ToString(),
                                StatusDoors = t.StatusDoors.ToString(),
                                Tempature = t.Tempature
                            }

                        ).Wait();
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                },
                context.CancellationToken);
        }
        catch (Exception e)
        {
            _logger.LogError(e.Message);
           
        }
      
       
    }
Related