C# gRPC服务端流客户端无法读取响应 NodeJS客户端正常运行问题排查
问题诱因
- 核心根因是异步等待逻辑缺失:你定义的
GetDataStreaming为async void类型,这类异步方法无法被外部调用者等待,Main方法触发该方法后会直接执行后续逻辑,进程直接退出,完全等不到流数据返回。 - 异常捕获逻辑失效:
async void方法抛出的异常不会被调用方的外层try/catch捕获,而是直接抛到同步上下文,所以你看不到任何错误输出。 - NodeJS客户端正常的原因:NodeJS的事件循环会自动持有活跃的异步IO操作,你注册的
data/end事件属于活跃监听,只要还有未完成的异步回调,进程就不会主动退出,因此可以正常接收流数据。
修复方案
- 将
GetDataStreaming的返回值从async void修改为async Task,支持外部等待 - 启用C# 7.1+支持的异步Main入口,等待流读取方法执行完成
- 补充channel资源释放逻辑
修正后的代码示例:
class Program { const int Port = 50051; // 改为异步Main入口 static async Task Main(string[] args) { try { Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); var client = new UserService.UserServiceClient(channel); // 等待异步方法执行完成 await GetDataStreaming(client); // 用完后安全关闭channel await channel.ShutdownAsync(); } catch (RpcException ex) { Console.WriteLine($"Error: {{Code: {ex.StatusCode}, Status: {ex.Status.Detail}}}"); } } // 返回值改为async Task private static async Task GetDataStreaming(UserService.UserServiceClient client) { AsyncServerStreamingCall<DataResponse> response = client.GetData(new Id { Id_ = 1 }); while (await response.ResponseStream.MoveNext()) { Console.WriteLine("Into while loop"); DataResponse current = response.ResponseStream.Current; Console.WriteLine($"{current.Data.ToStringUtf8()}"); } } }
内容的提问来源于stack exchange,提问作者J.F.
相关产品推荐
相关产品推荐

