c# - 如何使用 polly 启用超时策略

标签 c# async-await timeout cancellation polly

我正在尝试使用 polly 的超时策略。

    static void Main(string[] args)
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        timeoutPolicy().GetAwaiter().GetResult();

        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
        Console.ReadKey();
    }

    static async Task timeoutPolicy()
    {
        AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1); // setup the timeout limit to be 1 sec

        HttpResponseMessage response = await timeoutPolicy.ExecuteAsync((ct) => LongOperation(), CancellationToken.None);

    }

    static Task<HttpResponseMessage> LongOperation()
    {
        return Task<HttpResponseMessage>.Factory.StartNew(() =>
        {
            Thread.Sleep(5000); // Sleep 5 seconds
            return new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.BadRequest
            };

        });
    }

我预计 1 秒后会抛出异常,因为这是我设置的超时上限。但目前,不会抛出异常,LongOperation() 方法会在大约 5 秒后正常返回。

为什么超时策略在这种情况下不起作用?

最佳答案

Why does the timeout policy not work in this case?

波莉的TimeoutPolicy存在两种模式:

乐观模式是默认模式,因此您发布的代码使用此模式。但是(一)LongOperation()贴出的代码中不响应合作取消;所以该策略不会超时。

具有异步策略的悲观模式是 intentionally designed only to govern delegates which conform to the normal async patternThread.Sleep()在发布的LongOperation()完全同步;因此,只需切换到 TimeoutStrategy.Pessimistic,您的示例也不会超时。 .


TimeoutStrategy.Optimistic是通过HttpClient通话的最佳模拟,因为这些调用确实响应 CancellationToken

异步超时策略的乐观模式超时长操作可以用 await Task.Delay(...) 来模拟纪念CancellationToken , like this :

using System;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Polly;
using Polly.Timeout;

public class Program
{ 
    public static void Main(string[] args)
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        try {
            timeoutPolicy().GetAwaiter().GetResult();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
    }

    static async Task timeoutPolicy()
    {
        var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1); // setup the timeout limit to be 1 sec

        HttpResponseMessage response = await timeoutPolicy.ExecuteAsync((ct) => LongOperation(ct), CancellationToken.None);
    }

    static async Task<HttpResponseMessage> LongOperation(CancellationToken token)
    {
        await Task.Delay(5000, token);
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.BadRequest
        };
    }
} 

关于c# - 如何使用 polly 启用超时策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55459962/

相关文章:

c# - 如何使用 C# 以编程方式配置 ODBC 数据源

c# - DataGrid 的意外行为

c# - 语音合成器 "Input string was not in a correct format"

c# - 获取异步 : not returning HttpResponseMessage

c# - 将同步 Moq 模拟转换为异步

python - 在 Python 中安排超时

mysql - 不同的mysql超时是什么意思

c# - 如何生成动态for循环

javascript - AngularJS 取消超时

javascript - 如何在 Node.js 中实现同步执行的要求