HttpClient.SendAsync() 进行多次调用
HttpClient.SendAsync() makes multiple calls
我有一个 API 客户端,它是使用 API 的 Swagger 文档生成的。除了一个电话外,所有电话都工作正常。
不起作用的那个似乎会自动重试,而其他 none 会。它总共发送了四个请求。第二个紧接第一个之后,然后是第三个和第四个,间隔十秒。
这是为客户端生成的一些代码:
...
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
* _httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
* if (_shouldTrace)
{
ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
}
HttpStatusCode _statusCode = _httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
...
我在*
的两行设置了断点。使用 Fiddler,我可以看到所有四个调用都在命中第二个断点之前发生。
我在请求中找不到任何类型的重试策略。我查看了 SendAsync()
source,但它不包含我能看到的重试逻辑。
我对这个一头雾水
编辑 1:
每次发送请求,我都会得到 500 的回报。不过,这是目前预期的结果,因为 API 不完整。
答案来自一位同事。我需要手动定义重试策略。他想出了这个class(可能来自Google):
public class HttpTransientErrorDetectionStrategy
: ITransientErrorDetectionStrategy
{
private readonly List<HttpStatusCode> _statusCodes =
new List<HttpStatusCode>
{
HttpStatusCode.GatewayTimeout,
HttpStatusCode.RequestTimeout,
HttpStatusCode.ServiceUnavailable,
};
public HttpTransientErrorDetectionStrategy(bool isNotFoundAsTransient = false)
{
if (isNotFoundAsTransient)
_statusCodes.Add(HttpStatusCode.NotFound);
}
public bool IsTransient(Exception ex)
{
var we = ex as WebException;
if (we == null)
return false;
var response = we.Response as HttpWebResponse;
var isTransient = response != null
&& _statusCodes.Contains(response.StatusCode);
return isTransient;
}
它在客户端的 CustomInitialize()
方法中使用了这一行:
SetRetryPolicy(new RetryPolicy(new HttpTransientErrorDetectionStrategy(), 0));
我有一个 API 客户端,它是使用 API 的 Swagger 文档生成的。除了一个电话外,所有电话都工作正常。
不起作用的那个似乎会自动重试,而其他 none 会。它总共发送了四个请求。第二个紧接第一个之后,然后是第三个和第四个,间隔十秒。
这是为客户端生成的一些代码:
...
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
* _httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
* if (_shouldTrace)
{
ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
}
HttpStatusCode _statusCode = _httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
...
我在*
的两行设置了断点。使用 Fiddler,我可以看到所有四个调用都在命中第二个断点之前发生。
我在请求中找不到任何类型的重试策略。我查看了 SendAsync()
source,但它不包含我能看到的重试逻辑。
我对这个一头雾水
编辑 1:
每次发送请求,我都会得到 500 的回报。不过,这是目前预期的结果,因为 API 不完整。
答案来自一位同事。我需要手动定义重试策略。他想出了这个class(可能来自Google):
public class HttpTransientErrorDetectionStrategy
: ITransientErrorDetectionStrategy
{
private readonly List<HttpStatusCode> _statusCodes =
new List<HttpStatusCode>
{
HttpStatusCode.GatewayTimeout,
HttpStatusCode.RequestTimeout,
HttpStatusCode.ServiceUnavailable,
};
public HttpTransientErrorDetectionStrategy(bool isNotFoundAsTransient = false)
{
if (isNotFoundAsTransient)
_statusCodes.Add(HttpStatusCode.NotFound);
}
public bool IsTransient(Exception ex)
{
var we = ex as WebException;
if (we == null)
return false;
var response = we.Response as HttpWebResponse;
var isTransient = response != null
&& _statusCodes.Contains(response.StatusCode);
return isTransient;
}
它在客户端的 CustomInitialize()
方法中使用了这一行:
SetRetryPolicy(new RetryPolicy(new HttpTransientErrorDetectionStrategy(), 0));