如何使用 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 秒后正常返回。

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

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

波莉的TimeoutPolicy以两种模式存在:

  • TimeoutStrategy.Optimistic希望受治理的代表对CancelToken的合作取消做出回应。
  • TimeoutStrategy.Pessimistic允许调用代码不再等待响应合作取消的代理。

乐观模式是默认模式,因此您发布的代码使用此模式。但是(a)张贴的代码中的LongOperation()没有回应合作取消;因此,该策略不会超时。

具有异步策略的悲观模式旨在仅用于管理符合正常异步模式的委托。 发布LongOperation()中的Thread.Sleep()是完全同步的;因此,您的示例不会仅通过切换到TimeoutStrategy.Pessimistic来超时。


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

异步超时策略的乐观模式超时长操作可以通过await Task.Delay(...)遵守CancellationToken来模拟,如下所示:

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
};
}
} 

现在你正在使用超时Optimistic它期望你调用的delgate尊重并响应取消令牌。您的委托不会,在这种情况下,您需要使用超时Pessimistic以确保调用方不会等待通过定义的超时。

static async Task timeoutPolicy()
{
var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1, TimeoutStrategy.Pessimistic); // setup the timeout limit to be 1 sec
HttpResponseMessage response = await timeoutPolicy.ExecuteAsync((ct) => LongOperation(), CancellationToken.None);
} 

文档中所述的Polly 超时Optimistic是默认值。

正如@moutain旅行者已经指出的那样,乐观的超时要求您通过并配合超时取消。这已经通过使用HttpClient的 api 调用来处理,但在此示例案例中,您的代码将如下所示:

static async Task timeoutPolicy()
{
var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1, TimeoutStrategy.Optimistic); // setup the timeout limit to be 1 sec
HttpResponseMessage response = await timeoutPolicy.ExecuteAsync((ct) => LongOperation(ct), CancellationToken.None);
}
static Task<HttpResponseMessage> LongOperation(CancellationToken token)
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
var longTask = Task.Delay(5000);
while (!longTask.IsCompleted)
{
token.ThrowIfCancellationRequested();
}
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.BadRequest
};
});
} 

相关内容

  • 没有找到相关文章

最新更新