c# - 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:
Using RestSharp
Using HttpWebRequest
Sending two request (the same of two different requests), where the second request only takes 1,5 seconds, as it should.
I've tried request.Proxy = null; / ServicePointManager.UseNagleAlgorithm = false; / request.KeepAlive / ServicePointManager.DefaultConnectionLimit = 15;
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.
解决方案
我在 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(需要重新启动)或者更好,微软建议使用前缀策略。
更喜欢 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
以管理员身份运行
推荐阅读
- sql - 如果该字段存在于临时表中,则删除该字段
- azure - 具有安全 Azure 功能后端的静态 Blazor Web 程序集
- flutter - 我如何加载 100 幅图像以在颤动中撞击?
- php - 如何处理大量的 MySQL Select。多选可能吗?
- postgresql - 从表中删除用户
- java - 类作为字段的 Java 自定义注释(HAS-A 关系)
- python - 从另一列中获取具有至少一个指定值的值
- php - php中的异步Curl请求给出了错误的请求
- sql - 在会话表中计算用户登录的最快方法是什么?
- azure - Azure Policy - 拒绝缓存 Redis 的 IP 范围