.NET code-first gRPC服务调用过程中如何指定deadline?
.NET Code-First gRPC 指定Deadline的实现方法
客户端调用侧指定Deadline
Code-First模式下不需要手动实现抽象的ServerCallContext,直接通过CallContext的公开构造函数传入携带Deadline配置的CallOptions即可,示例如下:
- 首先你的服务契约定义需要保留
CallContext参数:
[ServiceContract] public interface IYourService { Task<YourResponse> YourMethod(YourRequest request, CallContext context = default); }
- 调用时构造带Deadline的
CallContext传入即可,注意Deadline必须使用UTC时间:
// 设定本次调用15秒后超时 var callContext = new CallContext(new CallOptions(deadline: DateTime.UtcNow.AddSeconds(15))); var response = await _yourServiceClient.YourMethod(request, callContext);
如果需要同时携带取消令牌,也可以直接传入CallOptions:
var cts = new CancellationTokenSource(); var callContext = new CallContext(new CallOptions(deadline: DateTime.UtcNow.AddSeconds(15), cancellationToken: cts.Token));
服务端侧使用Deadline
服务端的CallContext会自动携带客户端传入的Deadline配置,直接读取属性或绑定取消令牌即可,不需要额外配置:
public class YourService : IYourService { public async Task<YourResponse> YourMethod(YourRequest request, CallContext context) { // 直接读取客户端传入的Deadline var requestDeadline = context.Deadline; // 耗时操作绑定上下文的取消令牌,Deadline超时会自动触发取消 await LongTimeRunningProcess(context.CancellationToken); return new YourResponse(); } }
全局默认Deadline配置
如果需要给所有客户端调用设置统一的默认Deadline,可以在注册gRPC客户端时配置:
builder.Services.AddGrpcClient<IYourService>(options => { options.Address = new Uri("https://你的gRPC服务地址"); // 全局默认所有调用30秒超时,单个调用手动传的Deadline优先级更高 options.CallOptionsFactory = _ => new CallOptions(deadline: DateTime.UtcNow.AddSeconds(30)); });
常见误区说明
- 不需要自己实现
ServerCallContext,该类由gRPC运行时在服务端自动生成注入,业务侧不需要手动构造 - 不要修改
CallContext.Default不可变实例,直接构造新的CallContext传入自定义配置即可 - Deadline必须使用UTC时间,使用本地时间会有时差问题导致超时逻辑异常
内容的提问来源于stack exchange,提问作者nullPainter
相关产品推荐
相关产品推荐

