繁体   English   中英

C# 使用 Polly Retry 重试两个查询

[英]C# Retry two queries with Polly Retry

所以我有两个疑问:

var a = await _aQuery.Execute(aId);
var b = await _bQuery.Execute(bId);

我如何使用 Polly Retry 重试这些查询的执行,以便如果其中任何一个成功获得非空值,代码可以继续?

例如:每 200 毫秒重试 5 次,如果查询在ab上成功,则中断重试并继续。

为了简单起见,让我稍微改变一下你的两个操作。

static Random rnd = new();
static async Task<int?> OperationA()
{
    await Task.Delay(100); //Simulate I/O call's latency
    var number = rnd.Next();
    return number % 5 == 0 ? number : null;
}

static async Task<int?> OperationB()
{
    await Task.Delay(100);  //Simulate I/O call's latency
    var number = rnd.Next();
    return number % 4 == 0 ? number + 1 : null;
}
  • 我们有两个操作( OperationAOperationB ),它们将返回null或一个int
  • 它们的实现并不重要,它们只是用于演示目的

现在如果你需要定义一个重试策略

  • 如果两个操作都失败则触发
  • 最多触发5次
  • 每次尝试之间延迟 200 毫秒

那么你可以这样做:

var retryUntilGetResult = Policy<(int?, int?)>
    .HandleResult(((int? OpA, int? OpB) results) => !results.OpA.HasValue && !results.OpB.HasValue)
    .WaitAndRetryAsync(retryCount: 5, _ => TimeSpan.FromMilliseconds(200));
  • Policy<(int?, int?)>部分表示您的返回类型是一个包含两个可为空整数的元组
  • HandleResult部分表示,如果返回的元组 ( results ) 不包含任何 integer ( ....HasValue ),则应触发该策略
  • WaitAndRetryAsync部分说你想用这个策略装饰一个异步方法
  • 该政策最多应触发 5 次,但每次尝试之间应等待 200 毫秒

该策略的用法如下所示:

var result = await retryUntilGetResult.ExecuteAsync(async () =>
{
    Task<int?> opA = OperationA();
    Task<int?> opB = OperationB();
    await Task.WhenAll(opA, opB);
    return (await opA, await opB);
});
  • 我们触发了两个任务,我们正在等待两个任务完成
  • 然后我们返回一个新的元组,我们在其中传递异步操作的结果

为了完整起见,完整的源代码如下:

static async Task Main()
{
    var retryUntilGetResult = Policy<(int?, int?)>
        .HandleResult(((int? OpA, int? OpB) results) => !results.OpA.HasValue && !results.OpB.HasValue)
        .WaitAndRetryAsync(retryCount: 5, _ => TimeSpan.FromMilliseconds(200));

    var result = await retryUntilGetResult.ExecuteAsync(async () =>
    {
        Task<int?> opA = OperationA();
        Task<int?> opB = OperationB();
        await Task.WhenAll(opA, opB);
        return (await opA, await opB);
    });
    Console.WriteLine(result);
}

static Random rnd = new();
static async Task<int?> OperationA()
{
    await Task.Delay(100); //Simulate I/O call's latency
    var number = rnd.Next();
    return number % 5 == 0 ? number : null;
}

static async Task<int?> OperationB()
{
    await Task.Delay(100);  //Simulate I/O call's latency
    var number = rnd.Next();
    return number % 4 == 0 ? number + 1 : null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM