这段代码运行到最后,没有TimeoutRejectedException. 如果我将策略改为TimeoutStrategy.Pessimistic,它将在抛出TimeoutRejectedException之前进入执行逻辑两次.

如果我想用重试策略在超时后重试,我应该怎么做?(如果它超时,我想在暂停后重试,直到达到MaxRetries)?

让我的执行逻辑本身抛出超时是唯一的解决方案吗? (代码是.Net Framework4.8,它可以在LinqPad5和Polly v8.3.1上运行).

在这个设置中,Optimistic策略似乎并没有实际起到什么作用,不是吗?

var retry = Policy
    .Handle<Exception>()
    .Retry(1);

var timeout = Policy
    .Timeout(1, Polly.Timeout.TimeoutStrategy.Optimistic);

var wrap = Policy.Wrap(retry, timeout);

try
{
    wrap
        .Execute(() =>
        {
            "Enter executed logic".Dump();
            Thread.Sleep(5000);
            "Exit executed logic".Dump();
        });
}
catch(TimeoutRejectedException ex)
{
    ex.Message.Dump();
}

推荐答案

您需要设置TimeoutStrategy.Pessimistic,因为Thread.Sleep不使用CancellationToken来中断其等待.

var retry = Policy
    .Handle<Exception>()
    .Retry(1);

var timeout = Policy
    .Timeout(1, Polly.Timeout.TimeoutStrategy.Pessimistic);

var wrap = Policy.Wrap(retry, timeout);

try
{
    wrap
        .Execute(() =>
        {
            "Enter executed logic".Dump();
            Thread.Sleep(5000);
            "Exit executed logic".Dump();
        });
}
catch(TimeoutRejectedException ex)
{
    ex.Message.Dump();
}

乐观意味着您的待修饰方法可以通过CancellationToken

var retry = Policy
    .Handle<Exception>()
    .Retry(1);

var timeout = Policy
    .Timeout(1, Polly.Timeout.TimeoutStrategy.Optimistic);

var wrap = Policy.Wrap(retry, timeout);

try
{
    wrap
        .Execute(token =>
        {
            "Enter executed logic".Dump();
            Task.Delay(5000, token).Wait(token);
            "Exit executed logic".Dump();
        }, CancellationToken.None);
}
catch(TimeoutRejectedException ex)
{
    ex.Message.Dump();
}
  • 请注意,在本例中,我使用了不同的重载Execute.
  • It is not mandatory to pass the token to both Delay and Wait
    • 只要传到Wait:Task.Delay(5000).Wait(token);就足够了.

DotNet小提琴链接:https://dotnetfiddle.net/ei6iPA

Csharp相关问答推荐

当MD5被废弃时,如何在Blazor WASM中使用它?

利用.NET 8中的AddStandardResilienceDeliveries和AddStandardHedgingDeliveries实现Resiliency

.NET框架4.7.2项目如何引用.NET Core 2.2库?

Blazor:类型或命名空间名称Components在命名空间中不存在''

EF Core判断是否应用了AsSplitQuery()

从c#列表中删除额外的对象&对象&>从ASP.NET WebForm返回json响应

异步任务调用程序集

在Windows Plesk上发布ASP.NET Core 7 Web API-错误:无法加载文件或程序集';Microsoft.Data.SqlClient';

升级后发出SWITCH语句

VS 2022与VS 2019:如何/为什么创建额外的任务?

如何在.NET Maui中将事件与MVVM一起使用?

为什么此名称不再被识别?名称不存在于当前上下文中?

Blazor Server.NET 8中的Blazore.FluentValidation问题

我的命名管道在第一次连接后工作正常,但后来我得到了System.ObjectDisposedException:无法访问关闭的管道

Foreach非常慢的C#

RavenDb:为什么在字符串==空的情况下过滤会过滤得太多?

使用DI实例化带有动态参数的服务?

反序列化我以前使用System.Text.Json序列化的文件时出现异常

使用ITfoxtec.Identity.Saml2解析相同键多值SAML 2声明

外部应用&&的LINQ;左外部连接&类似于PostgreSQL的查询