如何优雅实现RequestMessage可等待 无侵入等待状态变更
业务场景
当前有两个运行中的微服务A与B,微服务A会在特定时机创建请求消息(或RequestMessage类型数组RequestMessage[])并发送至微服务B,RequestMessage结构示例如下:
public class RequestMessage { public Guid guid; public string result; public DateTime expirationDateTime; public RequestMessage() { guid = Guid.NewGuid(); result = "no_result"; } }
响应获取机制为框架提供服务类对应接口,请求发送后底层会在合适时机自动调用实现类的方法,开发者仅需负责TResolveRequestedMessage()方法的内部逻辑实现,示例代码如下:
public class RequestMessageResolver : IRequestMessageResolver { public bool TResolveRequestedMessage(Guid Id, string result) { // 按id从请求集合中查找对应请求,具体实现由开发者自行编写,实现方式不唯一 RequestCollection.Get(id).result = "resolved"; } }
核心问题
- 需让
RequestMessage支持await异步等待,但RequestMessage的接口定义已固定,无法修改 - 微服务A在收到对应请求的解析结果前,当前调用作用域内不得执行后续操作
- 等待响应期间,服务仍需正常响应状态查询、错误处理等其他类型请求
现有实现思路
- 方案1:创建持有
TaskCompletionSource的包装类,支持外部触发任务完成状态(示例代码如下)。该方案可实现需求,但需要编写大量额外包装逻辑才能达到预期效果。 - 方案2:调整包装类,实现
INotifyCompletion接口来替代TaskCompletionSource方案,但暂未验证该方案是否会带来较大性能开销、是否会无意义提升方案复杂度。
包装类实现示例代码:
public class RequestMessageWrapper { public TaskCompletionSource<bool> completionSource; public RequestMessage requestMessage; public RequestMessageWrapper(RequestMessage requestMessage) { completionSource = new TaskCompletionSource<bool>(); this.requestMessage = requestMessage; } public async Task GetResponseAsync() { // 需补充过期逻辑:当DateTime.Now > requestMessage.expirationDateTime时取消等待 await completionSource.Task; } }
内容的提问来源于stack exchange,提问作者Rey4eel
相关产品推荐
相关产品推荐

