[英]Polly with cancellation token is not working for synchronous thread
我是 Polly 的新手,所以与我尝试做的方法相比,可能有一种完全不同的方法,那完全没问题。 我的目标是:
TimeoutStrategy.Optimistic
clientTimeOut
的调用我正在使用取消令牌使调用超时,但不知何故,下面的代码不起作用。 我没有在添加取消令牌时创建新线程,而是使用相同的线程来遵守超时。 它是否总是需要在异步调用中添加取消令牌,即ExecuteAsync()
或使用另一个线程? 有人可以帮我解决以下代码有什么问题以及为什么超时不起作用吗?
注意:使用TimeoutStrategy.Pessimist
对我有用,但由于其他一些用例,我不能使用它。 我需要从请求上下文中读取 https 标头,我们将在使用异步调用时丢失此信息。 因此我需要使用同步调用。
public TResult ExecuteWrapper<TResult>(Func<CancellationToken ,TResult> func)
{
int attempts = 0;
int retryCounter = 3;
int waitTime = 1000;
int clientTimeOut = 10000;
var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(10000));
var cancellationToken = cts.Token;
RetryPolicy retryPolicy = Policy.Handle<Exception>().Retry(retryCounter);
retryPolicy = Policy.Handle<Exception>().WaitAndRetry(retryCounter, sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(this.waitTime), onRetry: (exception, timeSpan) =>
{
logRetryException(timeSpan, attempts++, exception);
});
PolicyWrap retrypolicywrap = retryPolicy.Wrap(Policy.Timeout(TimeSpan.FromMilliseconds(clientTimeOut), TimeoutStrategy.Optimistic));
return retrypolicywrap.Execute(func, cancellationToken);
}
public void BaseFunction(){
var result = ExecuteWrapper(() => DummyFunctionToSleepTheThread())
}
public string DummyFunctionToSleepTheThread(){
//Reading http header from the request context
//which will lost if we use async call
//Hence we can't use Task.Delay(milliseconds) here.
int milliseconds = 15000;
System.Threading.Thread.Sleep(milliseconds);
return "SUCCESS";
}
我尝试添加取消令牌,但它没有遵守超时。
您不能使用乐观超时策略来取消Thread
。 该策略使用CancellationToken
的合作行为。 Thread
不像Task
那样原生支持CancellationToken
。
所以,你有两个选择。 退回到悲观超时策略或使用Task
而不是Thread
。
据我从您的代码中可以看出,您还没有设计您的解决方案来利用Task
和 async-await。 所以,尽量使用悲观策略。
更新 #1
这是一个简单的应用程序,它展示了不同之处
(请注意, 超时的波纹管过载需要秒而不是毫秒)
public static void Main()
{
var optimisticTimeout = Policy.Timeout(1, TimeoutStrategy.Optimistic);
optimisticTimeout.Execute(ToBeDecoratedMethod);
var pessimisticTimeout = Policy.Timeout(1, TimeoutStrategy.Pessimistic);
try
{
pessimisticTimeout.Execute(() => ToBeDecoratedMethod());
}
catch(TimeoutRejectedException)
{
Console.WriteLine("Timed out");
}
}
public static void ToBeDecoratedMethod()
{
Console.WriteLine("Before Sleep");
Thread.Sleep(1_500);
Console.WriteLine("After Sleep");
}
output 将是:
Before Sleep
After Sleep
Before Sleep
Timed out
可以在这个 do.net fiddle link上找到工作代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.