-1

Here is my sample code:

var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(_configOptions.ResponseTimeout), TimeoutStrategy.Pessimistic);
            
try
{
    return await timeoutPolicy.ExecuteAsync(async ct => await Somemethod(request, ct), CancellationToken.None);
}
catch (TimeoutRejectedException ex)
{
    _//Some logging to go here/
}

configOptions.ResponseTimeout is configured in config file, I am expecting the method await Somemethod(request, ct), CancellationToken.None should throw TimeoutRejectedException based on the value given in config.

But it is not throwing any exception. Can anyone please help me to identify where I am going wrong?

Help will be much appreciated.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Anonymous
  • 1
  • 1
  • 1

1 Answers1

1

Optimistic timeout

The delegate does support cancellation.

The to be executed delegate

private static async Task SomeMethodAsync(CancellationToken ct = default)
{
    Console.WriteLine($"{nameof(SomeMethodAsync)} has been called.");
    await Task.Delay(15000, ct); //It is aware of the CancellationToken
}

The timeout policy

 private static AsyncTimeoutPolicy GetTimeoutPolicy
    => Policy
        .TimeoutAsync(
            TimeSpan.FromMilliseconds(1000),
            TimeoutStrategy.Optimistic,
            (context, timeout, _, exception) =>
            {
                Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\\.fff}: {exception.GetType().Name}");
                return Task.CompletedTask;
            });

The usage

var strategy = GetTimeoutPolicy;
var result = await strategy.ExecuteAsync(async (ct) => await SomeMethodAsync(ct), CancellationToken.None);

The output

SomeMethodAsync has been called.
Timeout   01.000    : TaskCanceledException
Unhandled exception. Polly.Timeout.TimeoutRejectedException: The delegate executed asynchronously through TimeoutPolicy did not complete within the timeout.
 ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
...

Pessimistic timeout

The delegate does not support cancellation.

The to be executed delegate

private static async Task SomeMethodAsync(CancellationToken ct = default)
{
    Console.WriteLine($"{nameof(SomeMethodAsync)} has been called.");
    await Task.Delay(15000); //It is NOT aware of the CancellationToken
}

The timeout policy

 private static AsyncTimeoutPolicy GetTimeoutPolicy
    => Policy
        .TimeoutAsync(
            TimeSpan.FromMilliseconds(1000),
            TimeoutStrategy.Pessimistic,
            (context, timeout, _, exception) =>
            {
                Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\\.fff}: {exception.GetType().Name}");
                return Task.CompletedTask;
            });

The usage

var strategy = GetTimeoutPolicy;
var result = await strategy.ExecuteAsync(async () => await SomeMethodAsync());

The output

SomeMethodAsync has been called.
Timeout   01.000    : TaskCanceledException
Unhandled exception. Polly.Timeout.TimeoutRejectedException: The delegate executed asynchronously through TimeoutPolicy did not complete within the timeout.
 ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
...
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • Hi Peter, is it necessary to use await Task.Delay(15000), – Anonymous Jan 11 '21 at 15:40
  • Hi Peter, is it necessary to use await Task.Delay(15000)?,SomeMethodAsync() is calling another async method which should actually give timeout(because it's third party service),using await Task.Delay(15000) is like forcing the method to timeout in specified milliseconds. Correct me if i am wrong? – Anonymous Jan 11 '21 at 15:51
  • @Anonymous No, obviously not. It is just a simulation of an async call. Call whatever method you like there. But please keep in mind that in case of optimistic timeout handling the `cancellationToken` should be passed all the way down. – Peter Csala Jan 11 '21 at 15:52
  • I am using pessimistic strategy. – Anonymous Jan 11 '21 at 15:56
  • In case of pessimistic you don't have to pass the cancellation token to the lower layer. – Peter Csala Jan 11 '21 at 16:05
  • After removing cancellation token from the calling method, it is still not throwing timeout exception. Also, i can't use await Task.Delay(1000) as it is simulation.i want my calling method to throw timeout exception as per time specified in TimeSpan.FromMilliseconds(1000). Where am i going wrong? – Anonymous Jan 11 '21 at 16:36
  • thanks for your help.using await Task.Delay(1000) works, but i can't use it in my real code. Please suggest what i am doing wrong. – Anonymous Jan 11 '21 at 16:54
  • Please amend your question to reflect to the current state. Please also include the Somemethod body as well. – Peter Csala Jan 11 '21 at 16:58
  • Please **amend your question** and do not post code as comment. – Peter Csala Jan 11 '21 at 17:59
  • @Anonymous Could you please extend your original question to share with us your updated code to be able to help you with that? – Peter Csala Jan 15 '21 at 07:26