【问题标题】:Polly Policy.TimeoutAsync not giving TimeoutRejected exceptionPolly Policy.TimeoutAsync 没有给出 TimeoutRejected 异常
【发布时间】:2021-01-11 06:14:42
【问题描述】:

这是我的示例代码:

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

但它没有抛出任何异常。 谁能帮我确定我哪里出错了?

我们将不胜感激。

【问题讨论】:

  • _configOptions.ResponseTimeout 的值是多少?

标签: c# dotnet-httpclient polly


【解决方案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.
...

【讨论】:

  • 嗨彼得,是否有必要使用 await Task.Delay(15000),
  • 嗨彼得,是否有必要使用 await Task.Delay(15000)?,SomeMethodAsync() 正在调用另一个异步方法,该方法实际上应该给出超时(因为它是第三方服务),使用 await 任务。 Delay(15000) 就像强制方法在指定的毫秒内超时。如果我错了,请纠正我?
  • @Anonymous 不,显然不是。它只是一个异步调用的模拟。在那里调用任何你喜欢的方法。但请记住,在乐观超时处理的情况下,cancellationToken 应该一直向下传递。
  • 我正在使用悲观策略。
  • 在悲观的情况下不必将取消令牌传递给下层。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
相关资源
最近更新 更多