我为typed Http client配置了Polly。这是我的Program.cs
:
serviceCollection.AddSingleton<IPolicyBuilder, PolicyBuilder>();
serviceCollection
.AddHttpClient<ICustomHttpClient, CustomHttpClient>()
.AddPolicyHandler((serviceProvider, httpRequestMessage) =>
{
var policyBuilder = serviceProvider.GetRequiredService<IPolicyBuilder>();
return policyBuilder.BuildGenericPolicy();
});
我键入的客户端:
public class CustomHttpClient: ICustomHttpClient
{
private readonly HttpClient _httpClient;
public NotificationsApiHttpClient(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
public async Task<HttpResponseMessage> SendEmailCommandAsync(string jsonEmailCommand)
{
return await _httpClient.PostAsync(new Uri("dummy uri"), new StringContent("dummy content"));
}
我需要发送这批HTTP请求,并且对响应不感兴趣。我注入我键入的CustomHttpClient。为了提高性能,我尝试这样做:
var tasks = new List<Task>();
foreach(item in collection)
{
tasks.Add(_customHttpClient.SendEmailCommandAsync("dummyJsonContent");
}
await Task.WhenAll(tasks);
如果我的数组中有大约100多个项目,我总是会遇到此异常:
System.Threading.Tasks.TaskCanceledException
HResult=0x8013153B
Message=The operation was canceled.
Source=System.Net.Http
StackTrace:
at System.Net.Http.HttpConnection.<SendAsyncCore>d__61.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnectionPool....
Inner Exception 1:
IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request.
Inner Exception 2:
SocketException: The I/O operation has been aborted because of either a thread exit or an application request
PS。抱歉,因为它太长,所以不得不将stacktrace缩小
它的工作原理与此无一例外:
foreach(item in collection)
{
await _customHttpClient.SendEmailCommandAsync("dummyJsonContent");
}