Политика Polly.TimeoutAsync не выдает исключение, вызванное временем ожидания

#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. В случае пессимизма вам не нужно передавать токен отмены на нижний уровень.