首页 > 解决方案 > Slow first HTTP request with HttpWebRequest

问题描述

So I'm trying to use HttpWebRequest in my C# plugin for Revit(BIM software), to send a request to my API. But every time I try this, it takes way longer than the request would take in Chrome/Firefox/Postman.

If I send my request with Postman, it takes about 1 to 1,5 seconds. But if I send it within my application, it takes about 21 to 21,5 seconds. So it seems like there is some kind of timeout created by the HttpWebrequest, but I can't seem to figure out why this is the case.

My code:

static public string Get(string baseURI, Dictionary<string, string> requestParameters)
    {
        ServicePointManager.UseNagleAlgorithm = false;
        ServicePointManager.DefaultConnectionLimit = 15;
        string requestURI = baseURI;

        if (requestURI.Length != 0)
        {
            foreach (KeyValuePair<string, string> parameter in requestParameters)
            {
                if (requestURI[requestURI.Length - 1] != '?')
                {
                    requestURI = requestURI + '&';

                }
                requestURI = requestURI + parameter.Key + "=" + parameter.Value;
            }
        }

        HttpWebRequest request = WebRequest.Create(requestURI) as HttpWebRequest;

        request.Method = "GET";
        string results = string.Empty;
        request.Proxy = null;
        request.KeepAlive = false;

        HttpWebResponse response;
        using (response = request.GetResponse() as HttpWebResponse)
        {
            // Get the response stream  
            StreamReader reader = new StreamReader(response.GetResponseStream());
            results = reader.ReadToEnd();
            reader.Close();
            response.Close();
        }

        return results;
    }

I've tried the following:

I can't think of anything else, and the debugger doesn't give me any useful information on what's it doing in those 20 seconds.

标签: c#.netrevit-apirevit

解决方案


我在 Autohotkey 中处理这个问题。但基本上使用相同的 ComObjCreate("WinHttp.WinHttpRequest.5.1")。

我发现在 Windows 的网络适配器设置中关闭 IPV6 协议解决了这个问题。

所以它真的可能是服务器端与 IPV6 的兼容性。20 秒后回退到 IPV4 并且任何下一个请求运行良好。只需尝试打开 IPV6。

我将深入研究如何强制 WinHttpRequest 使用 IPV4。

一些资源:WINHTTP_OPTION_IPV6_FAST_FALLBACK

https://docs.microsoft.com/en-us/windows/win32/winhttp/option-flags

https://docs.microsoft.com/en-us/windows/win32/winhttp/iwinhttprequest-option

https://github.com/wine-mirror/wine/blob/master/include/winhttp.h

https://www.rfc-editor.org/rfc/rfc6555

不幸的是,这个参数与 WinHttpRequest.5.1 不兼容,因为它是 WinHttp 的参数。

解决方法是在注册表中禁用 IPV6(需要重新启动)或者更好,微软建议使用前缀策略。

https://kb.firedaemon.com/support/solutions/articles/4000160803-prioritising-ipv4-over-ipv6-on-windows-10

更喜欢 IPV4 而不是 IPV6

commandline: 
netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 46 4

更喜欢 IPV6 而不是 IPV4

commandline: 
netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 35 4

以管理员身份运行


推荐阅读