Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically changing HttpClient.Timeout in .NET

Tags:

I need to change a HttpClient.Timeout property after it made a request(s). When I try, I get an exception:

This instance has already started one or more requests. Properties can only be modified before sending the first request.

Is there any way to avoid this?

like image 443
AsValeO Avatar asked May 21 '14 18:05

AsValeO


People also ask

How do I change HttpClient timeout per request?

You can't change HttpClient. Timeout after the instance has been used. You have to pass in a CancellationToken instead. There are other key points to know when trying to control HttpClient's timeout.

What does HttpClient timeout do?

the Connection Manager Timeout (http. connection-manager. timeout) – the time to wait for a connection from the connection manager/pool.

Is C# HttpClient thread safe?

HttpClient is a very important class in the . NET/. NET Core ecosystem. HttpClient is designed as a shared instance that is also a thread-safe if used properly.


2 Answers

There isn't much you can do to change this. This is just default behavior in the HttpClient implementation.

The Timeout property must be set before the GetRequestStream or GetResponse method is called. From HttpClient.Timeout Remark Section

In order to change the timeout, it would be best to create a new instance of an HttpClient.

client = new HttpClient();
client.Timeout = 20; //set new timeout
like image 159
Andrew Smith Avatar answered Sep 30 '22 15:09

Andrew Smith


Internally the Timeout property is used to set up a CancellationTokenSource which will abort the async operation when that timeout is reached. Since some overloads of the HttpClient methods accept CancellationTokens, we can create helper methods to have a custom timeouts for specific operations:

public async Task<string> GetStringAsync(string requestUri, TimeSpan timeout)
{
    using (var cts = new CancellationTokenSource(timeout))
    {
        HttpResponseMessage response = await _httpClient.GetAsync(requestUri, cts.Token)
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsStringAsync();
    }
}
like image 33
Monsignor Avatar answered Sep 30 '22 16:09

Monsignor