Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# - HttpClient with HttpClientHandler cancellation not working

I am facing an issue with HttpClient (.NETStandard v2.1, System.Net.Http, targeting mono runtime). I want to set timeout for HttpClient per request by passing a cancellation token in SendAsync. It is working properly when using the parameterless constuctor of HttpClient, but it is ignored when passing to the HttpClient costructor an instance of HttpClientHandler. The operation is cancelled after 75 secs.

To illustrate:

public static async Task<HttpResponseMessage> Send()
{
    var req = new HttpRequestMessage(HttpMethod.Get, new 
            Uri("someURL"));
    var handler= new HttpClientHandler{CookieContainer = new 
            CookieContainer()};  
    /*var client = new HttpClient(); <--- This is working */          
    var client = new HttpClient(handler);
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
    cts.Token.Register(() => Debug.WriteLine("TASK CANCELLED"));
    return await client.SendAsync(req, cts.Token);
}

After 5 secs the debug output writes "TASK CANCELLED" but the SendAsync continues for a total of 75 secs. If i use the parameterless constructor the SendAsync cancells after 5 secs.

I need the HttpClientHandler to use the CookieContainer property. What am i missing here?

EDIT

After further investigation and the hints of @Lasse Vågsæther Karlsen i figured out the following:

  1. .NET Core 3 runtime

    • If the url is not reachable or internet connection is down the HttpClient throws HttpRequestException after 3 secs
    • Otherwise it cancels as expected after 5 secs
  2. Mono runtime (Xamarin.Forms project)

    • If the url is not reachable or internet connection is down the HttpClient throws OperationCanceledException after 75 secs
    • Otherwise it cancels as expected after 5 secs

Maybe it is related to this https://forums.xamarin.com/discussion/5941/system-net-http-httpclient-timeout-seems-to-be-ignored.

Still an open issue though...

like image 531
Γαβριήλ Σαμώλης Avatar asked Oct 11 '19 10:10

Γαβριήλ Σαμώλης


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the difference between Python and C and C++?

C is a compiled language. C++ is a compiled language. Python is an interpreted language.

What is the difference between Python and C?

Python is an object oriented programming language. C is a middle level language as it binds the bridges between machine level and high level languages. Python is a high-level language as the translation of Python code takes place into machine language, using an interpreter. C is a compiled programming language.

Is Python better than C?

Ease of development – Python has fewer keywords and more free English language syntax whereas C is more difficult to write. Hence, if you want an easy development process go for Python. Performance – Python is slower than C as it takes significant CPU time for interpretation. So, speed-wise C is a better option.


1 Answers

The simplest method I found was using the Polly library https://github.com/App-vNext/Polly and wrapping the methods that would not honor the cancellation token. You don't even need a cancellation token. Example:

var policy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(3000),
    TimeoutStrategy.Pessimistic,
    (context, timespan, task) => throw new Exception("Cannot connect to server."));

await policy.ExecuteAsync(async () =>
{
    var httpClient = new HttpClient();
    var response = await httpClient.PostAsync(...);
    response.EnsureSuccessStatusCode();
    ...
});
like image 105
Hakakou Avatar answered Nov 15 '22 09:11

Hakakou