gpt4 book ai didi

c# - 用于工作流的 C# 中的 Polly 模式?

转载 作者:行者123 更新时间:2023-12-04 17:16:41 24 4
gpt4 key购买 nike

我有一个这样的工作流程:

  • 调用 API 方法
  • 如果抛出任何异常但超时,程序会记录该异常并抛出它。

  • 如果抛出超时,程序必须调用另一个 API 方法。
  • 调用另一个 API 方法后,如果一切正常,程序将返回结果。
  • 否则程序会抛出异常并记录下来。


  • 两种 API 方法具有相同类型的结果。
    我想用波利政策来实现这一点。
    这是我的示例代码:
    var retryPolicy = Policy
    .Handle<HttpRequestException>(ex => ex.StatusCode == HttpStatusCode.RequestTimeout)
    .RetryAsync(1, async (exception, retryCount) =>
    await CallAnotherAPI());

    var fallbackPolicy = Policy<HttpResponseMessage>
    .Handle<Exception>()
    .FallbackAsync((r, c, ct) => throw r.Exception,
    async (r, c) =>
    {
    Log(r.Message);
    });

    var result = await fallbackPolicy
    .WrapAsync(retryPolicy)
    .ExecuteAsync(async () =>
    {
    await CallAPI();
    });
    但它不起作用,并且一直在执行 fallbackPolicy。我如何编写代码,如果 retryPolicy 为真,则不会执行 fallbackPolicy?

    最佳答案

    如果我正确理解您的工作流程,那么您根本不需要重试策略。回退策略就足够了。
    所以,假设 CallApiCallAnotherApi是这样实现的:

    private static HttpClient client = new HttpClient();
    public static async Task<HttpResponseMessage> CallAPI()
    {
    return await client.GetAsync("http://httpstat.us//408");
    }

    public static async Task<HttpResponseMessage> CallAnotherAPI()
    {
    var response = await client.GetAsync("http://httpstat.us//500");
    response.EnsureSuccessStatusCode();
    return response;
    }
  • 我用过 httpstatus.us模拟某些 http 状态码
  • CallApi总是会因请求超时而失败
  • CallAnotherApi总是会抛出 HttpRequestException因为Ensure方法调用

  • 现在让我们看看策略定义和用法:
    public static async Task Main(string[] args)
    {
    var fallbackPolicy = Policy<HttpResponseMessage>
    .HandleResult(msg => msg.StatusCode == HttpStatusCode.RequestTimeout)
    .FallbackAsync(async (_) => await CallAnotherAPI());

    HttpResponseMessage result;
    try
    {
    result = await fallbackPolicy
    .ExecuteAsync(async () =>
    {
    return await CallAPI();
    });
    }
    catch (Exception ex) {
    Console.WriteLine(ex.Message); //TODO: replace with logging
    throw;
    }

    Console.WriteLine(result.StatusCode);
    }
  • 仅当响应的状态代码为 408
  • 时才应触发回退策略
  • ExecuteAsync如果 CallApi 将抛出异常或 CallAnotherApi抛出

  • 让我们一一看看不同的场景 CallApi成功
    public static async Task<HttpResponseMessage> CallAPI()
    {
    return await client.GetAsync("http://httpstat.us//200");
    }
    输出
    OK
    CallApi失败
    public static async Task<HttpResponseMessage> CallAPI()
    {
    var response = await client.GetAsync("http://httpstat.us//500");
    response.EnsureSuccessStatusCode();
    return response;
    }
    输出
    Response status code does not indicate success: 500 (Internal Server Error).
    然后应用程序因为 throw; 而崩溃 CallApi超时和 CallAnotherApi成功
    public static async Task<HttpResponseMessage> CallAPI()
    {
    return await client.GetAsync("http://httpstat.us//408");
    }

    public static async Task<HttpResponseMessage> CallAnotherAPI()
    {
    var response = await client.GetAsync("http://httpstat.us//200");
    response.EnsureSuccessStatusCode();
    return response;
    }
    输出
    OK
    CallApi超时和 CallAnotherApi失败
    public static async Task<HttpResponseMessage> CallAPI()
    {
    return await client.GetAsync("http://httpstat.us//408");
    }

    public static async Task<HttpResponseMessage> CallAnotherAPI()
    {
    var response = await client.GetAsync("http://httpstat.us//500");
    response.EnsureSuccessStatusCode();
    return response;
    }
    输出
    Response status code does not indicate success: 500 (Internal Server Error).
    然后应用程序因为 throw; 而崩溃

    关于c# - 用于工作流的 C# 中的 Polly 模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68560615/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com