I'm new to Polly so there may be a completely different approach compared to the one I'm trying to do and that would be perfectly OK. My goals are this:
TimeoutStrategy.Optimistic
clientTimeOut
I am using cancellation token to timeout the call but somehow the below code is not working. I am not creating a new thread while adding a cancellation token but using the same thread to honoured the timeout. Does it always need to add the cancellation token in asynchronous call ie ExecuteAsync()
or use another thread for it? Can someone help me with what is wrong with the below code and why timeout is not working?
Note: Using TimeoutStrategy.Pessimist
will work for me but I can't use this due to some other usecase. I need to read the https headers from request context, and we will loose this information when using async call. Hence I need to use the sync call.
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";
}
I tried adding the cancellation token but it did not honoured the timeout.
You can't use optimistic timeout strategy to cancel a Thread
. This strategy uses the co-operative behaviour of the CancellationToken
. Thread
s do not natively support CancellationToken
like Task
s.
So, you have two options. Fall back to pessimistic timeout strategy or use Task
instead of Thread
.
As far as I can tell from the your code you haven't designed your solution to take advantage of Task
s and async-await. So, try to use the pessimistic strategy.
UPDATE #1
Here is a simple app which demonstrates the difference
( Please note that bellow overload of Timeout requires seconds not milliseconds )
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");
}
The output will be:
Before Sleep
After Sleep
Before Sleep
Timed out
The working code can be found on this do.net fiddle link .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.