runtime: HttpWebRequest hits 1s timeout when resolving http://localhost on Win10 (.NET Framework is fast)

Consider the following method (error/exception handling omitted for brevity:

public virtual string MakeHttpRequest(Uri fullUri, string httpMethod, string requestBody)
{
    string responseString = string.Empty;
    HttpWebRequest request = HttpWebRequest.Create(fullUri) as HttpWebRequest;
    request.Method = httpMethod;
    request.Timeout = 30000;
    request.Accept = "application/json,image/png";
    if (request.Method == "POST")
    {
        string payload = requestBody;
        byte[] data = Encoding.UTF8.GetBytes(payload);
        request.ContentType = "application/json;charset=utf-8";
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();
    }

    HttpWebResponse webResponse = request.GetResponse() as HttpWebResponse;
    using (Stream responseStream = webResponse.GetResponseStream())
    using (StreamReader responseStreamReader = new StreamReader(responseStream, Encoding.UTF8))
    {
        responseString = responseStreamReader.ReadToEnd();
    }
    return responseString;
}

Executing this method against a server running on localhost yields wildly different execution times when run via the full .NET Framework vs. .NET Core. I have a demo project that shows the discrepancy, making calls to a locally running HTTP server, that server being the Chromium project’s chromedriver.exe, used to automate the Chrome browser. When running the executables created by that project, you can see the following typical outputs (as run on Windows 10, build 16288):

Run against .NET Core 2.0:

Starting test… Starting ChromeDriver 2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a) on port 9515 Only local connections are allowed. Started session 946394531499259b7442073c0e26060d Navigating to http://www.google.com Navigation complete Making 10 HTTP calls to localhost, logging the elapsed time… Elapsed time for HTTP call: 1038 milliseconds Elapsed time for HTTP call: 1016 milliseconds Elapsed time for HTTP call: 1015 milliseconds Elapsed time for HTTP call: 1011 milliseconds Elapsed time for HTTP call: 1012 milliseconds Elapsed time for HTTP call: 1024 milliseconds Elapsed time for HTTP call: 1013 milliseconds Elapsed time for HTTP call: 1027 milliseconds Elapsed time for HTTP call: 1013 milliseconds Elapsed time for HTTP call: 1014 milliseconds Test finished. Press <Enter> to exit.

Running against the full .NET Framework 4.5:

Starting test… Starting ChromeDriver 2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a) on port 9515 Only local connections are allowed. Started session 81c2bbd21a0d89354b2dead8d52ee982 Navigating to http://www.google.com Navigation complete Making 10 HTTP calls to localhost, logging the elapsed time… Elapsed time for HTTP call: 35 milliseconds Elapsed time for HTTP call: 7 milliseconds Elapsed time for HTTP call: 12 milliseconds Elapsed time for HTTP call: 5 milliseconds Elapsed time for HTTP call: 4 milliseconds Elapsed time for HTTP call: 7 milliseconds Elapsed time for HTTP call: 4 milliseconds Elapsed time for HTTP call: 6 milliseconds Elapsed time for HTTP call: 5 milliseconds Elapsed time for HTTP call: 5 milliseconds Test finished. Press <Enter> to exit.

I would expect similar performance between framework versions. Absent that, I would expect there to be settings to modify to the HttpWebRequest object that would yield similar performance as a workaround.

[EDIT] C# syntax highlighing by @karelz

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 5
  • Comments: 27 (17 by maintainers)

Commits related to this issue

Most upvoted comments

We were hit by this very same issue. We use Selenium extensively and noticed that on Windows 10 machines our tests slowed to a crawl when we switched to .Net core. What is strange is on virtual machines, running Windows 2016 they were still running really fast.

I found @jimevans’s demo project and started experimenting.

I tried disabling IPv6 on the network adapter but it made no difference. It seems like “localhost” uses some special loopback adapter so disabling IPv6 on your other network adapters won’t do anything!

This solved the problem for me: https://superuser.com/questions/586144/disable-ipv6-loopback-on-windows-7-64-bit/681967#681967

I also confirmed that Windows 2016 servers already have this ::ffff:0:0/96 higher on the priority list, hence why they don’t suffer from the 1000ms delay.

@jimevans It may be an option to make the ServerUrl in DriverService.cs read/write so that we can set it to 127.0.0.1 as a workaround.

I’ll point out here, to forestall the inevitable comment mentioning it, that changing from System.Net.HttpWebRequest to System.Net.Http.HttpClient in the .NET Core case doesn’t resolve the issue. The performance is the same. In the aforementioned demo project, there is an alternative implementation that can be used in the .NET Core case that utilizes the newer class. The performance is comparable.

I’ve started using .NET Core 2.0 with Entity Framework Core 2.0. A lot of changes from .NET 4.5 for me as I used the Http Response Message. Now I’m returning an ‘object’ that automatically gets converted to Json. I’ve received some response handshake errors that worry me. Thinking I’m getting timed out sometimes. I am sending requests via an observable from an Angular 2 node.js web app. My web page is loading without the results from the .NET api. Eventually it will load but sometimes it looks like it takes 25 or more seconds. Have not measured but it seems like a lifetime in web response time. I use some console.log commands and notice that they show up late. Granted I’m still learning the observable and am not certain about any implied REST asynchronous thing going on. As a user though I’m not going to want to see a page without data that suddenly appears later. I’d just start to reload the page after a few seconds. I use Google Chrome usually but I gave IE a try just to compare and its about the same. I am also using Visual Studio 2017 Community (free) run on IIS Express (localhost) and my Angular web app runs on the Cloud 9 IDE (free version) so my issue could be limited resources. I’ve also noticed that Visual Studio 2017 Community IDE is slow to respond. Just switching files takes a while. It often freezes and goes unresponsive. I’m leaning toward Visual Studio as the weak link. My Angular 2 web apps with an observable usually get a quick response back when calling Express against MongoDB. If I continue to have problems with Visual Studio I’m thinking that I may look to Java Spring REST as an alternative to Express. Java is still a big market and I don’t want to stare at my laptop waiting for my back end tools to deliver services.

Can you try changing your tests so that they use http://127.0.0.1 in the URL instead of http://localhost?

When using 127.0.0.1, I get response times of ~10ms, whereas localhost give me response times of ~1020ms, so it looks like there’s a 1-second timeout you’re hitting.