4

As the title says I'd like to disable the pipelining functionality BUT still make use of the connection pool (so KeepAlive=False is not an option). The reason is that longer requests may prevent shorter requests from executing fast, but opening up a new connection for every requests is significantly slower.

I'm doing this:

_webRequestHandler = new WebRequestHandler();
_webRequestHandler.AllowPipelining = false;

_httpClient = new HttpClient(_webRequestHandler);
await _httpClient.SendAsync(request);

servicePoint = ServicePointManager.FindServicePoint(request.RequestUri);

This seems to have no effect: The ServicePoint.SupportsPipelining property is still true and the WebRequestHandler is only setting the Pipelined property of the HttpWebRequest but nothing on the HttpRequestMessage so basically setting AllowPipelining on the WebRequestHandler has no effect (?).

Am I missing something here? I'm sure this is a common scenario - how can I achieve that?

srudin
  • 261
  • 2
  • 13
  • `longer requests may prevent shorter requests from executing fast` How you find that? And take a look at [this](https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.defaultconnectionlimit?view=netframework-4.7.2) – skyoxZ Nov 02 '18 at 08:59
  • **SupportsPipelining** is totally different than **AllowPipelining**. If you support something than you can decide to allow its use or not. If you did not support something it does not mattter if you allow its use or not, you cannot use it at all. Supports is a fact and Allow is a decision but the decision will not influence the fact – Sir Rufo Nov 02 '18 at 09:34
  • @skyoxZ I don't see what your link is supposed to help? For the explanation to your question please refer to https://stackoverflow.com/questions/14810890/what-are-the-disadvantages-of-using-http-pipelining (see "Head of line blocking"). – srudin Nov 05 '18 at 05:44
  • @SirRufo Ok. But how can I achieve to turn it off? – srudin Nov 05 '18 at 05:45
  • Build a new class inherited from HttpClient which ensures setting AllowPipelining to false and use that class. You can also have a factory for that, or ... – Sir Rufo Nov 05 '18 at 07:38
  • @SirRufo AllowPipelining does not exist on the HttpClient. Please read my question again to understand the problem about this. – srudin Nov 05 '18 at 09:06
  • Of course I know that, but read **your own code** to understand how to build an HttpClient instance where AllowPipelining is set to false. The answer is in the first three lines of your posted code sample. (create a handler, set AllowPipelining to false, create a HttpClient with that handler) – Sir Rufo Nov 05 '18 at 10:25
  • @SirRufo Sorry, I don't get it. Are you telling me that my code is perfect already? I know that according to documentation this is the way to do it. My whole question is that this doesn't work in reality. – srudin Nov 06 '18 at 01:46
  • "doesn't work in reality" because the SupportsPipelining property is still true? – Sir Rufo Nov 06 '18 at 06:02
  • @SirRufo No, because the AllowPipelining = false value is not passed on to the request: "The ServicePoint.SupportsPipelining property is still true and the WebRequestHandler is only setting the Pipelined property of the HttpWebRequest but nothing on the HttpRequestMessage so basically setting AllowPipelining on the WebRequestHandler has no effect" – srudin Nov 06 '18 at 10:27

1 Answers1

0

The situation remains:

  • Setting ConnectionClose to true on the HttpClient issues a KeepAlive: false and establishes a new connection for every request. This has a significant negativ performance impact and is therefore undesired.
  • Setting ConnectionClose to false reuses the connections - but only when they are free (no pending request). Having a large number of simultanous requests will still open a large number of connections.
  • Setting the ConnectionLimit on the HttpClient to Environment.ProcessorCount * 12 (as suggested by MS) is limiting the number of open connections to the specified value. Unfortunately this is resulting in random unresponsiveness shutting the whole system down! I assume this happens when all open connections are used, pipelining is activated and then... something happens. This is why I wanted to turn pipelining off (just wait until any open connection becomes free and reuse it).

But it seems this can not be set this way, at least I couldn't find it and no one could help me. And expecting MS to fix the real problem is... well, unlikely.

So I ended up setting the ConnectionLimit to 1000 which seems to be high enough that the problem never occurrs (in our system). Not a real fix though - feel free to post if you have a better solution...

srudin
  • 261
  • 2
  • 13