首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Polly WaitAndRetryAsync在一次重试后挂起

Polly WaitAndRetryAsync在一次重试后挂起
EN

Stack Overflow用户
提问于 2019-06-26 17:15:08
回答 1查看 2.2K关注 0票数 2

我在非常基本的场景中使用Polly在HTTP调用失败时执行指数回退:

代码语言:javascript
复制
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    return await HandleTransientHttpError()
        .Or<TimeoutException>()
        .WaitAndRetryAsync(4, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)))
        .ExecuteAsync(async () => await base.SendAsync(request, cancellationToken).ConfigureAwait(false));
}

private static PolicyBuilder<HttpResponseMessage> HandleTransientHttpError()
{
    return Policy
        .HandleResult<HttpResponseMessage>(response => (int)response.StatusCode >= 500 || response.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
        .Or<HttpRequestException>();
}

我有一个测试应用程序接口,它只在while(true)中创建HttpListener和循环。目前,我正在尝试测试当每个呼叫接收500时,客户端是否正确重试。

代码语言:javascript
复制
while (true)
{
    listener.Start();
    Console.WriteLine("Listening...");
    HttpListenerContext context = listener.GetContext();
    HttpListenerRequest request = context.Request;

    HttpListenerResponse response = context.Response;
    response.StatusCode = (int)HttpStatusCode.InternalServerError;

    //Thread.Sleep(1000 * 1);
    string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
    response.ContentLength64 = buffer.Length;
    System.IO.Stream output = response.OutputStream;
    output.Write(buffer, 0, buffer.Length);
    output.Close();
    listener.Stop();
}

有了上面的代码,所有的工作都很好,重试分别在等待3,9,27和81秒后发生。

但是,如果我取消对Thread.Sleep调用的注释,客户端会重试一次,然后就会挂起,直到调用在其他三次重试中超时,这不是正确的行为。

同样的事情也发生在实际的生产API上,这让我相信这不是我的测试API的问题。

EN

回答 1

Stack Overflow用户

发布于 2022-03-03 17:10:08

对于.NET框架和在HttpClient中使用Polly的已知问题,这似乎是一个合适的解决方法。我们必须在重试时处理结果,以便允许多个请求。请参阅关于原始问题here的讨论,以及描述解决方法here的另一讨论。我只是对它进行了简单的测试,以确定它是否有效,但还没有充分研究它可能存在的副作用。

代码语言:javascript
复制
Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(msg => RetryableStatusCodesPredicate(msg.StatusCode))
.RetryAsync(retryCount, onRetry: (x, i) =>
{
    x.Result.Dispose(); // workaround for https://github.com/aspnet/Extensions/issues/1700
}));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56769241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档