#c# #dotnet-httpclient #polly
#c# #dotnet-httpclient #polly
Вопрос:
Вот мой пример кода:
var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(_configOptions.ResponseTimeout), TimeoutStrategy.Pessimistic);
try
{
return await timeoutPolicy.ExecuteAsync(async ct => await Somemethod(request, ct), CancellationToken.None);
}
catch (TimeoutRejectedException ex)
{
_//Some logging to go here/
}
configOptions.ResponseTimeout
настроен в файле конфигурации, я ожидаю, что метод await Somemethod(request, ct)
CancellationToken.None
должен выдавать TimeoutRejectedException
на основе значения, указанного в конфигурации.
Но это не вызывает никаких исключений. Может кто-нибудь, пожалуйста, помочь мне определить, где я ошибаюсь?
Помощь будет высоко оценена.
Комментарии:
1. Какова ценность
_configOptions.ResponseTimeout
этого ?
Ответ №1:
Оптимистичный тайм-аут
Делегат поддерживает отмену.
Подлежащий выполнению делегат
private static async Task SomeMethodAsync(CancellationToken ct = default)
{
Console.WriteLine($"{nameof(SomeMethodAsync)} has been called.");
await Task.Delay(15000, ct); //It is aware of the CancellationToken
}
Политика тайм-аута
private static AsyncTimeoutPolicy GetTimeoutPolicy
=> Policy
.TimeoutAsync(
TimeSpan.FromMilliseconds(1000),
TimeoutStrategy.Optimistic,
(context, timeout, _, exception) =>
{
Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\.fff}: {exception.GetType().Name}");
return Task.CompletedTask;
});
Использование
var strategy = GetTimeoutPolicy;
var result = await strategy.ExecuteAsync(async (ct) => await SomeMethodAsync(ct), CancellationToken.None);
На выходе
SomeMethodAsync has been called.
Timeout 01.000 : TaskCanceledException
Unhandled exception. Polly.Timeout.TimeoutRejectedException: The delegate executed asynchronously through TimeoutPolicy did not complete within the timeout.
---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
...
Пессимистический тайм-аут
Делегат не поддерживает отмену.
Подлежащий выполнению делегат
private static async Task SomeMethodAsync(CancellationToken ct = default)
{
Console.WriteLine($"{nameof(SomeMethodAsync)} has been called.");
await Task.Delay(15000); //It is NOT aware of the CancellationToken
}
Политика тайм-аута
private static AsyncTimeoutPolicy GetTimeoutPolicy
=> Policy
.TimeoutAsync(
TimeSpan.FromMilliseconds(1000),
TimeoutStrategy.Pessimistic,
(context, timeout, _, exception) =>
{
Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\.fff}: {exception.GetType().Name}");
return Task.CompletedTask;
});
Использование
var strategy = GetTimeoutPolicy;
var result = await strategy.ExecuteAsync(async () => await SomeMethodAsync());
Вывод
SomeMethodAsync has been called.
Timeout 01.000 : TaskCanceledException
Unhandled exception. Polly.Timeout.TimeoutRejectedException: The delegate executed asynchronously through TimeoutPolicy did not complete within the timeout.
---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
...
Комментарии:
1. Привет, Питер, нужно ли использовать задачу ожидания. Задержка (15000),
2. Привет, Питер, нужно ли использовать задачу ожидания. Задержка (15000)?, SomeMethodAsync() вызывает другой асинхронный метод, который фактически должен давать тайм-аут (потому что это сторонняя служба), используя await Task . Задержка (15000) — это все равно, что заставить метод использовать тайм-аут в указанные миллисекунды. Поправьте меня, если я ошибаюсь?
3. @Anonymous Нет, очевидно, нет. Это просто имитация асинхронного вызова. Вызовите там любой метод, который вам нравится. Но, пожалуйста, имейте в виду, что в случае оптимистичного тайм-аута обработка
cancellationToken
должна быть передана полностью.4. Я использую пессимистическую стратегию.
5. В случае пессимизма вам не нужно передавать токен отмены на нижний уровень.