У меня есть код, который проверяет некоторые данные, вызывая ряд других служб. Я запускаю все вызовы параллельно, а затем жду, пока хотя бы один из них не завершится. Если какой-либо из запросов терпит неудачу, меня не волнует результат других вызовов.
Я делаю звонки с помощью HttpClient
, и я передал HttpMessageHandler
, который выполняет кучу журналов. По сути:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
try
{
response = await base.SendAsync(request, cancellationToken);
}
catch (OperationCanceledException ex)
{
LogTimeout(...);
throw;
}
catch (Exception ex)
{
LogFailure(...);
throw;
}
finally
{
LogComplete(...);
}
return response;
}
Нет той части, с которой у меня возникают проблемы, это когда я отменяю запросы. Когда я отменяю запрос, я делаю это намеренно, поэтому я не хочу, чтобы он регистрировался как тайм-аут, но, похоже, нет никакой разницы между отменой и реальным тайм-аутом.
Есть ли способ это сделать?
Изменить: мне нужно немного пояснить. Служба, выполняющая параллельные вызовы, передает CancellationTokens с тайм-аутом:
var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2));
Поэтому, когда серверу требуется более двух секунд для ответа, я получаю OperationCanceledException
, и если я вручную отменяю источник токена (например, потому что другой сервер вернул ошибку через 1 секунду), я все равно получаю OperationCanceledException
. В идеале я мог бы посмотреть на CancellationToken.IsCancellationRequested
, чтобы определить, было ли оно отменено из-за тайм-аута, в отличие от явного запроса на отмену, но похоже, что вы получаете одно и то же значение независимо от как оно был отменен.