首页 > 解决方案 > 如何优雅地停止读取 gRPC 流并在客户端 C# 上断开连接

问题描述

我有 gRPC 服务定义如下

service ConsumerService 
{
    stream Message Consume(SubscriptionRequest);
}

客户端看起来像这样:

var consumer = new ConsumerService.ConsumerServiceClient(<channel>);
AsyncServerStreamingCall<Message> proxy = consumer.ConsumeAsync(subRequest));

while (!gracefulShutdown)
    await proxy.ResponseStream.MoveNext(cts.Token);

// todo: tell the server that client is not going to read responses anymore..
await proxy.ResponseStream.CompleteAsync(); // I would like to have method like this

当 gracefulShutdown 设置为 true 时,我需要客户端优雅地停止读取响应。我该怎么做呢?

如果我只是停止阅读并关闭频道,服务器将其视为中止。

标签: c#grpc

解决方案


正如我在互联网上检查的那样,我没有找到任何优雅的方法。我希望使用 CancellationTokenSource。只需使用try,catch。看起来这是预期的行为。来自 grpc 团队的评论

由于意外情况,取消将用于强制终止未完成的呼叫,您不应依赖它们来处理应用程序中的基本工作流程

使用像这里这样的 catch 块来检查异常

catch (RpcException e) when (e.Status.StatusCode == StatusCode.Cancelled)
{
    Console.WriteLine("Streaming was cancelled from the client!");
}

有关 github C# Clean Cancellation的更多信息


推荐阅读