Polly 的 TimeoutAsync 未命中 onTimeoutAsync

Polly's TimeoutAsync doesn't hit onTimeoutAsync

提问人:KwarcPL 提问时间:7/31/2023 最后编辑:Peter CsalaKwarcPL 更新时间:7/31/2023 访问量:56

问:

我创建了如下代码:

var timeout = Policy.TimeoutAsync(5, TimeoutStrategy.Pessimistic, (c, ts, t) =>
{
    _logger.LogInformation("TEST");
});

await timeout.ExecuteAsync(async () =>
{
    Thread.Sleep(10000);
    await Task.CompletedTask;
});

由于未知原因,它没有击中,但是当我更改为和更改为它时,它正在工作。_logger.LogInformation("TEST")TimeoutAsyncTimeoutExecuteAsyncExecute

C# 超时 波莉

评论

2赞 Fildor 7/31/2023
尝试而不是await Task.Delay(TimeSpan.FromSeconds(10));Thread.Sleep

答:

0赞 Peter Csala 7/31/2023 #1

对于 Polly,您可以通过许多不同的方式定义超时策略:

  • 用于乐观或悲观的取消处理
  • 对于异步或同步方法

同步政策 + 悲观

var syncTimeoutPessimistic = Policy.Timeout(
    TimeSpan.FromSeconds(3), 
    TimeoutStrategy.Pessimistic, 
    (_, __, ___) =>
{
    "onTimeout is fired".Dump();
});

try
{
    syncTimeoutPessimistic.Execute(() =>
    {
        Thread.Sleep(5_000);
        "Decorated operation is finished".Dump();
    });
} 
catch(TimeoutRejectedException)
{
    "Timeout has kicked in".Dump();
}

同步政策 + 乐观

var syncTimeoutOptimistic = Policy.Timeout(
    TimeSpan.FromSeconds(3), 
    TimeoutStrategy.Optimistic, 
    (_, __, ___) =>
{
    "onTimeout is fired".Dump();
});

try
{
    syncTimeoutOptimistic.Execute((ct) =>
    {
        var result = Task.Run(() => { Thread.Sleep(5_000); return Task.CompletedTask; });
        result.Wait(ct);
        "Decorated operation is finished".Dump();
    }, CancellationToken.None);
} 
catch(TimeoutRejectedException)
{
    "Timeout has kicked in".Dump();
}

它更像是一种黑客攻击,而不是一种建议的方法。

异步策略 + 悲观

var asyncTimeoutPessimistic = Policy.TimeoutAsync(
    TimeSpan.FromSeconds(3), 
    TimeoutStrategy.Pessimistic, 
    (_, __, ___) =>
{
    "onTimeout is fired".Dump();
    return Task.CompletedTask;
});

try
{
    await asyncTimeoutPessimistic.ExecuteAsync(async () =>
    {
        await Task.Delay(5_000);
        "Decorated operation is finished".Dump();
    });
} 
catch(TimeoutRejectedException)
{
    "Timeout has kicked in".Dump();
}

异步 + 乐观

var asyncTimeoutOptimistic = Policy.TimeoutAsync(
    TimeSpan.FromSeconds(3), 
    TimeoutStrategy.Optimistic, 
    (_, __, ___) =>
{
    "onTimeout is fired".Dump();
    return Task.CompletedTask;
});

try
{
    await asyncTimeoutOptimistic.ExecuteAsync(async (ct) =>
    {
        await Task.Delay(5_000, ct);
        "Decorated operation is finished".Dump();
    }, CancellationToken.None);
} 
catch(TimeoutRejectedException)
{
    "Timeout has kicked in".Dump();
}

在所有情况下,您都应看到以下输出:

Dumping object(String)
 onTimeout is fired
Dumping object(String)
 Timeout has kicked in

相关 dotnet fiddle 链接: https://dotnetfiddle.net/bYLTuF

0赞 KwarcPL 7/31/2023 #2

正如菲尔多所说,这就是原因。替换它解决了我的问题。Thread.Sleep(10000)Task.Delay(TimeSpan.FromSeconds(10))