0

我正在尝试使用 DelegatingHandler 实现重试,但我也想设置 HttpCompletionOption。

我的代码如下所示:

public class RetryHandler : DelegatingHandler
{
    private readonly int MaxRetries;

    public RetryHandler(HttpMessageHandler innerHandler, int retryCount = 3)
        : base(innerHandler)
    {
        MaxRetries = retryCount;
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        HttpResponseMessage response = null;
        for (var i = 0; i < MaxRetries; i++)
        {
            response = await base.SendAsync(request, cancellationToken);
            if (response.IsSuccessStatusCode)
            {
                return response;
            }
        }

        return response;
    }
}

    static void Main(string[] args)
    {
        using (var client = new HttpClient(new RetryHandler(new HttpClientHandler())))
        {
            var request = new HttpRequestMessage(HttpMethod.Post, "https://ptsv2.com/t/smz9v-1564979884/post");
            var myResult = client.SendAsync(request).Result;
            Console.WriteLine(myResult.ToString());
        }

        Console.ReadLine();
    }

正如您所看到的,没有通过继承 DelegatingHandler 来设置 HttpCompletionOption 的选项,我尝试创建 CustomDelegatinghandler,但在这种情况下,我无法像在 main 方法中使用的那样使用new RetryHandler(new HttpClientHandler()) 。

有没有办法实现具有/支持以下签名的 DelegatingHandler(或自定义)?

protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, HttpCompletionOption option,
        CancellationToken cancellationToken)

任何帮助,将不胜感激。谢谢,

4

1 回答 1

2

您不需要包含HttpCompletionOption在消息处理程序签名中,因为处理HttpCompletionOption是 的责任HttpClient,而不是HttpMessageHandler

一个HttpMessageHandler必须启动一个发送请求的任务,并Task<HttpResponseMessage>尽可能早地返回一个。一般来说,它不应该对响应内容执行任何缓冲(好吧,除非它是为缓冲目的而创建的中间件),这就是它不接收HttpCompletionOption. 它应该总是表现得好像它已经通过了HttpCompletionOption.ResponseHeadersRead

指定的预期方法HttpCompletionOption是将其包含在对方法重载的调用中,HttpClient例如GetAsyncor SendAsync

client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

粗略地说,HttpClient处理HttpCompletionOption如下:

  1. 调用消息处理程序并获得一个Task<HttpResponseMessage>见代码
  2. 如果HttpCompletionOption.ResponseHeadersRead指定,则完成:将任务返回给调用者(参见代码
  3. 如果HttpCompletionOption.ResponseContentRead指定,则返回 , 的任务HttpContent.LoadIntoBufferAsync作为原始任务的延续Task<HttpResponseMessage>参见代码
于 2019-08-05T08:47:56.503 回答