Polly如何重复发送同一HTTP请求?底层实现原理揭秘
Polly重试时如何规避HttpRequestMessage只能发送一次的限制
首先明确问题本质:HttpRequestMessage的Content流默认是单向读取的,发送后流的位置到了末尾,再次发送时无法重新读取,直接触发InvalidOperationException。Polly的解决核心是每次重试前创建原始请求的副本,而非复用实例。
底层运作逻辑(结合DelegatingHandler)
AddPolicyHandler最终注册的是PolicyHttpMessageHandler,这个类继承自DelegatingHandler,负责拦截HTTP请求并应用Polly策略。- 当触发重试时,该Handler不会直接复用原始
HttpRequestMessage,而是调用请求实例的Clone()方法(或自定义克隆逻辑)生成新的请求对象:- 克隆过程会复制原始请求的方法、URI、Headers等元数据;
- 对于
HttpContent,如果是缓冲型内容(如StringContent、ByteArrayContent),会重新生成一个包含相同数据的新流; - 如果是不可缓冲的内容(如绑定到网络流的
StreamContent),Polly允许通过PolicyHttpMessageHandlerOptions的CloneHttpRequestMessageAsync委托自定义克隆逻辑,确保重试时Content可用。
- 每次重试发送的都是全新的
HttpRequestMessage实例,自然不会触发重复发送的异常。
额外注意点
如果你的请求使用了非缓冲型Content,一定要自行实现克隆逻辑,否则重试时仍会因为流无法重新读取而失败。比如可以在克隆时重新读取原始数据并创建新的StreamContent。
内容的提问来源于stack exchange,提问作者silkfire
相关产品推荐
相关产品推荐

