Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何快速获取.Net Http请求_C#_.net_Http_Httpwebrequest_Libcurl - Fatal编程技术网

C# 如何快速获取.Net Http请求

C# 如何快速获取.Net Http请求,c#,.net,http,httpwebrequest,libcurl,C#,.net,Http,Httpwebrequest,Libcurl,我需要一个Http请求,我可以在.Net中使用,这需要不到100毫秒的时间。我可以在我的浏览器中实现这一点,所以我真的不明白为什么代码中会出现这样的问题 我试过WinHTTP和WebRequest.Create,它们都超过500毫秒,这在我的用例中是不可接受的 下面是我试图通过的简单测试的例子。(WinHttpFetcher是我编写的一个简单的包装器,但它提供了Get请求的最简单的示例,我不确定它是否值得粘贴。) 我使用LibCurlNet得到了可以接受的结果,但是如果同时使用该类,我会得到访问

我需要一个Http请求,我可以在.Net中使用,这需要不到100毫秒的时间。我可以在我的浏览器中实现这一点,所以我真的不明白为什么代码中会出现这样的问题

我试过WinHTTP和WebRequest.Create,它们都超过500毫秒,这在我的用例中是不可接受的

下面是我试图通过的简单测试的例子。(WinHttpFetcher是我编写的一个简单的包装器,但它提供了Get请求的最简单的示例,我不确定它是否值得粘贴。)

我使用LibCurlNet得到了可以接受的结果,但是如果同时使用该类,我会得到访问冲突。另外,由于它不是托管代码,必须复制到bin目录,所以在我的开源项目中部署它并不理想

有没有其他可以尝试的实现方案

    [Test]
    public void WinHttp_Should_Get_Html_Quickly()
    {
        var fetcher = new WinHttpFetcher();
        var startTime = DateTime.Now;          
        var result = fetcher.Fetch(new Uri("http://localhost"));
        var endTime = DateTime.Now;
        Assert.Less((endTime - startTime).TotalMilliseconds, 100);
    }
    [Test]
    public void WebRequest_Should_Get_Html_Quickly()
    {
        var startTime = DateTime.Now;
        var req = (HttpWebRequest) WebRequest.Create("http://localhost");
        var response = req.GetResponse();
        var endTime = DateTime.Now;
        Assert.Less((endTime - startTime).TotalMilliseconds, 100);
    }
使用该类获得准确的计时

然后,通过在发布代码中多次运行计时测试,确保没有看到未优化代码或JIT编译的结果。放弃前几个电话以消除JIT的影响,然后接受其余电话的平均消息

VS.NET具有测量性能的功能,您可能还希望使用类似的工具来查看您在“在线”上花费了多少时间,并检查是否是您的IIS/web服务器造成了延迟

500毫秒是一段很长的时间,在这些课程中有可能达到10毫秒,所以不要放弃希望

更新#1:

这是一篇很棒的文章,讨论了微观基准测试以及避免看到JIT这样的东西需要做什么:

您不太了解微观基准测试,但这里有很多最佳实践

更新#2:

所以,我写了这个控制台应用程序(使用VS.NET2010)

。。。然后按Ctrl-F5键。它被编译为debug,但我没有调试就运行了它,结果得到了63ms。我在我的Windows7笔记本电脑上运行这个,因此会返回默认的IIS7主页。再次运行它,我会得到类似的时间

运行发布版本会给出50ms55ms范围内的时间


这是我所期望的数量级。显然,如果您的网站正在执行ASP.NET重新编译,或回收应用程序池,或进行大量后端处理,那么您的时间安排将有所不同。如果您的标记是大量的,那么它也会有所不同,但是您在客户端使用的类都不应该是这里的速率限制步骤。这将是网络和/或远程应用程序处理。

尝试将HttpWebRequest实例的代理属性设置为null。 如果可行,那么尝试将其设置为GlobalProxySelection.GetEmptyWebProxy(),这似乎更正确

您可以在此处阅读更多信息: -WebRequest慢吗


2018年更新:从评论中提取此信息


System.Net.GlobalProxySelection已过时。此类已被弃用。请改用WebRequest.DefaultWebProxy访问和设置全局默认代理。使用null而不是GetEmptyWebProxy()jirarium 2017年7月22日5:44进行基准测试时,最好至少放弃前两个计时,因为它们可能会扭曲结果:

  • 计时1:主要由JIT开销控制,即将字节码转换为本机代码的过程
  • 计时2:JIT代码可能的优化过程
之后的计时将更好地反映重复性能

下面是一个测试工具的示例,该工具将自动忽略JIT和优化过程,并在取平均值以断言性能之前运行一个测试一组迭代次数。正如您所看到的,JIT传递需要花费大量的时间

准时制:410.79ms

优化:0.98ms

10次迭代的平均值:0.38ms

代码:

[测试]
public void WebRequest\u应该\u快速获取\u Html\u()
{
私家侦探证词=10;
private const int max毫秒=100;
动作测试=()=>
{
WebRequest.Create(“http://localhost/iisstart.htmGetResponse();
};
AssertTimedTest(测试,最大毫秒,测试);
}
私有静态void AssertTimedTest(整数迭代、整数最大值、动作测试)
{
double jit=执行(测试);//忽略jit传递
WriteLine(“JIT:{0:F2}ms.”,JIT);
双重优化=执行(测试);//忽略优化过程
WriteLine(“Optimize:{0:F2}ms.”,Optimize);
双总时间=0;
对于(inti=0;i
问题不在于HttpWebRequest。我通常会在13毫秒内收到连接到本地主机的请求。你确定这不是服务器吗?+1总是会丢弃至少前两个结果,这将是JIT,然后可能是优化传递。我在发布模式下尝试了很多次,但仍然很慢。我真的怀疑秒表是否会在超过30毫秒左右的量级上起作用,我相信我的测试仍然有效。如果你能在10毫秒内用这些类来制作,我很乐意看到它。我能做到这一点的唯一方法是循环并平均结果。但是对于这个用例,我在第一个请求中使用它是唯一重要的,因为在应用程序池的每个web请求中,它都像第一个请求一样对待它。我刚刚尝试了这个,得到了63毫秒。我编写了一个控制台应用程序,稍后我会将其放入我的答案中。System.Net.GlobalProxySelection已过时。此类已被弃用。请使用WebRequest.DefaultWebProxy代替ac
class Program
{
    static void Main(string[] args)
    {
        var stopwatch = Stopwatch.StartNew();
        var req = (HttpWebRequest)WebRequest.Create("http://localhost");
        var response = req.GetResponse();
        Console.WriteLine(stopwatch.ElapsedMilliseconds);            
    }
}
[Test]
public void WebRequest_Should_Get_Html_Quickly()
{
    private const int TestIterations = 10;
    private const int MaxMilliseconds = 100;

    Action test = () =>
    {
       WebRequest.Create("http://localhost/iisstart.htm").GetResponse();
    };

    AssertTimedTest(TestIterations, MaxMilliseconds, test);
}

private static void AssertTimedTest(int iterations, int maxMs, Action test)
{
    double jit = Execute(test); //disregard jit pass
    Console.WriteLine("JIT:{0:F2}ms.", jit);

    double optimize = Execute(test); //disregard optimize pass
    Console.WriteLine("Optimize:{0:F2}ms.", optimize);

    double totalElapsed = 0;
    for (int i = 0; i < iterations; i++) totalElapsed += Execute(test);

    double averageMs = (totalElapsed / iterations);
    Console.WriteLine("Average:{0:F2}ms.", averageMs);
    Assert.Less(averageMs, maxMs, "Average elapsed test time.");
}

private static double Execute(Action action)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    action();
    return stopwatch.Elapsed.TotalMilliseconds;
}