46

I had a low performance problem with HTTP requests on .NET. The HTTP GET request to a REST API on the localhost took about 500 ms to complete. I spent a lot of time to fix it. I have tried many ways: HttpClient, HttpWebRequest, WebClient and RestSharp. None of them work. Most solutions on the Internet said to set Proxy parameter to null but it still won't work faster.

The only way I found to reduce this time is to set the Keep-Alive parameter of request to false:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.KeepAlive = false;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

This works great. Time is reduced to 7-10 ms. But now in some reasons I need to use HttpClient instead of HttpWebRequest. And I can't find how to set Keep-Alive to false for HttpClient. The only thing I found is how to set it to true by setting a "connection" header to "Keep-Alive".

I am using this code for POST request by HttpClient:

HttpClient _http = new HttpClient();
_http.DefaultRequestHeaders.Accept.Clear();
_http.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
_http.DefaultRequestHeaders.Add("Keep-Alive", "timeout=600");

var content = new StringContent(
request, Encoding.UTF8, "application/%appname%+xml");
content.Headers.ContentType.Parameters.Add(
    new NameValueHeaderValue("type", "payload")
);

HttpResponseMessage response = await _http.PostAsync(uri, content);

And it still takes about 500-600 ms to complete.

pjpscriv
  • 866
  • 11
  • 20
Vaskrol
  • 471
  • 1
  • 4
  • 8
  • http://stackoverflow.com/questions/15211812/using-a-keep-alive-connection-in-winrts-httpclient-class ... just an idea ... –  Apr 01 '16 at 13:53
  • @AndreasNiedermair Thanks, this is a first link in the Google search result. I've already tried this: content.Headers.Add("Keep-Alive", "false"); But this takes more than 500 ms to complete too. – Vaskrol Apr 01 '16 at 14:04
  • This discussion also: https://github.com/dotnet/runtime/issues/30104 – Pavel Biryukov Nov 23 '20 at 08:37

5 Answers5

47

Use this code to disable HTTP Keep-Alive on the client:

_http.DefaultRequestHeaders.ConnectionClose = true;

This will set Connection request header to close.

Pavel Chuchuva
  • 22,633
  • 10
  • 99
  • 115
40

When you set HttpWebRequest.KeepAlive = true the header set is Connection: keep-alive

When you set HttpWebRequest.KeepAlive = false the header set is Connection: close

So you will need

_http.DefaultRequestHeaders.Add("Connection", "close");
Jerry Joseph
  • 1,002
  • 8
  • 14
3

See code below:

HttpClient cli;
...
cli.DefaultRequestHeaders.Add("Connection", "keep-alive");
cli.DefaultRequestHeaders.Add("Keep-Alive", "600");
Riad Baghbanli
  • 3,105
  • 1
  • 12
  • 20
  • It doesn't work. I've updated a question with my code. – Vaskrol Apr 01 '16 at 14:15
  • 1
    The sample you posted that "works great" is the equivalent of KeepAlive=False. The header you state you tried is the equivalent of KeepAlive=True. You are doing the opposite of what you need to do. – Matt Jun 07 '17 at 19:47
1

I hope this can help you, I have tested

_client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
0

I wrote HttpClientHandler, and in the handler just before the request I deleted the header "Connection". In this case, it sets the default "Connection: keep-alive". Even if before that you put it in the HttpClient by default, set properties, etc. Check your handlers.