You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#异步gRPC客户端调用Go服务阻塞,同步调用正常求解决方案

问题描述

用Go实现的gRPC服务端,和Go客户端配合运行正常。但在.NET 6 Windows项目中编写C#客户端时:

  • 调用同步方法NewCall完全正常:
client.NewCall( new CallRequest { Title = notification.Title }, deadline: DateTime.UtcNow.AddSeconds( 5 ), cancellationToken: cancellationToken );
  • 调用异步方法NewCallAsync时,服务端业务逻辑执行完成后上下文被取消,客户端卡在await行一直等待结果,设置截止时间或CancellationToken都无法解决:
await client.NewCallAsync( new CallRequest { Title = notification.Title }, deadline: DateTime.UtcNow.AddSeconds( 5 ), cancellationToken: cancellationToken );
可能的解决方案

1. 排查Go服务端的响应发送逻辑

检查Go服务端处理请求的代码,确认在异步调用场景下是否正确发送了响应。如果服务端仅执行完业务逻辑,但未调用grpc.SendAndClose或正确返回响应对象,会导致客户端持续等待。比如同步调用的逻辑路径正确返回了响应,但异步分支遗漏了响应发送步骤。

2. 校验gRPC版本兼容性

确保.NET项目中Grpc.Net.Client、Google.Protobuf等依赖包的版本,和Go服务端使用的gRPC大版本保持一致。版本不兼容可能引发异步通信时的协议解析异常,建议将.NET侧的gRPC相关包升级至最新稳定版测试。

3. 检查服务端上下文的取消逻辑

在Go服务端添加日志,打印上下文取消的原因(ctx.Err()),确认是否是服务端代码中错误触发了上下文取消。比如某些异步逻辑里误用context.WithCancel并提前执行取消操作,导致gRPC框架认为请求终止,未向客户端返回响应。

4. 调整C#客户端的调用写法

尝试不传入自定义cancellationToken,改用CancellationToken.None测试;也可以换一种方式手动处理异步调用,避免封装方法可能存在的问题:

var call = client.NewCallAsync(new CallRequest { Title = notification.Title }, deadline: DateTime.UtcNow.AddSeconds(5));
var response = await call.ResponseAsync;

5. 排查Windows环境的网络限制

Windows的防火墙、代理设置可能干扰gRPC的异步通信。尝试临时关闭防火墙测试,或确保gRPC使用的端口已被防火墙允许。另外确认系统支持HTTP/2(.NET 6在Windows上默认支持,但部分环境可能存在配置异常)。


内容的提问来源于stack exchange,提问作者Sascha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:41:17