1

I have a simple program that uses System.Net.Http.HttpClient which works like this:

// Get existing or create new httpclient if there isn't one instace of it already 
mClient = GetHttpClient();
var startTime = DateTime.Now;

var res = await mClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

var executeMethodTime = DateTime.Now.Subtract(startTime).TotalMilliseconds;
mLog.Info("restPostExecuteMethodTime : {0}", executeMethodTime);

It makes a simple request to the API and waits for the response. The content of the request is very small just some simple objects nothing too big.

The API side looks like this:

public async Task<IHttpActionResult> DoWork([FromBody]TemplateInput templateInput)
{
        IHttpActionResult res;
        var startTime = DateTime.Now;

        // do logic 
        var auditTime = DateTime.Now.Subtract(startTime).TotalMilliseconds;
        mLog.Info($"auditTime {auditTime}");
        return res;
}

Here is the logging generated by that code :

2020-07-15 09:12:19.7472|auditTime 204.9607|
2020-07-15 09:12:24.8172|executeMethodTime : 5321.9861|

What surprised me is that the API took over 5 seconds to return the result when in fact all the logic in the API took only about 200 milliseconds to finish executing. But it took whole entire 5 seconds to return the result back to the requester.

I checked the network and there were no problems.

It made no sense to me. Is there anything in HttpClient that could potentially affect the response speed? To the point that it would cost request 5 seconds?

I first thought it was caused by proxy setting inside httpClient so I tried to set proxy to false when creating httpClient it turned out to make no difference to speed.

If anyone has any idea - please let me know.

nanobots
  • 437
  • 9
  • 23
  • 1
    You don't have to create `HttpClient` for every call – Pavel Anikhouski Jul 15 '20 at 17:46
  • I agree ,but that has nothing to do with the delay as you can see the delay happens after the api side already finished executing the code and is trying to return it back to the request. It took 5 whole seconds to get back to the sender which is what i am confused about. – nanobots Jul 15 '20 at 18:00
  • infact I didn't created for every call I modified the code slightly to show the construct but I'll revert it to the way it is in my program – nanobots Jul 15 '20 at 18:07
  • It would be helpful to know if the delay comes before your server receives the request or if the delay comes after the server has sent the response. There are different root causes associated with each. For example, if the delay comes before your server receives the request, it could be due to DNS lookup, CRL checks, etc. required to negotiate the initial connection. You might also consider using Swagger or SOAPUI or some other known good test client to check the timing. – John Wu Jul 15 '20 at 18:23
  • it happens after the server has sent the response as you can see in the logs. It was 9:12:19 when the last line of api was executed. Then it took whole 5 seconds to 09:12:24 until the request program receives the response – nanobots Jul 15 '20 at 18:26
  • Where is the api? Same network? – Iria Jul 15 '20 at 19:18
  • Just a thought, breakpoints to see the time – Iria Jul 15 '20 at 19:19
  • Did you try respect `IDisposable` for `HttpResponseMessage`? `using (var res = await mClient.SendAsync(...)) { ... }`. `HttpRequestMessage` and `HttpContent` are `IDisposable` too. – aepot Jul 15 '20 at 20:26
  • [Does this answer your question?](https://stackoverflow.com/a/62802872/12888024) – aepot Jul 15 '20 at 20:36
  • no I am not disposing httpResponseMessage but why would that affect performance? and yes the api is on the same network. both on internal network. Also I checked the memory usage it is stable and no spiking in memory usage at all. – nanobots Jul 17 '20 at 15:51
  • @aepot ok one thing I left out which is important is that both of these code exist in apis. My program consist of multiple micro services talking to each other . the process goes like this: Frontend page => GatewayService => Actual Api that does the work. the code I am showing is Gateway calling actual api that does the work. Since the HttpClient is going to be different almost every other request with different header content type etc. Is reusing the same one as a static wise? – nanobots Jul 17 '20 at 15:58
  • @nanobots 2 things I use for `HttpClient`: 1) Singleton or static `HttpClient` (`IHttpClientFactory` for complicated cases) 2) `IDisposable`s must be disposed correctly. And it runs for me as fast as it can. And yes, not disposed `HttpResponseMessage` or `HttpRequestMessage` may affect the performance of further requests. I don't remember why but it actually is. Something like not freeing transfering socket in time. Behavior depends on underlying transport class which is different in various framework types. – aepot Jul 17 '20 at 16:34

0 Answers0