HTTPWebResponse + StreamReader非常慢

时间:2009-05-23 11:03:02

标签: c# performance web-crawler httpwebresponse streamreader

我正在尝试在C#中实现有限的网络抓取工具(仅限几百个网站) 使用HttpWebResponse.GetResponse()和Streamreader.ReadToEnd(),也尝试使用StreamReader.Read()和循环来构建我的HTML字符串。

我只下载大约5-10K的页面。

一切都很慢!例如,平均GetResponse()时间约为半秒,而平均StreamREader.ReadToEnd()时间约为5秒!

所有网站都应该非常快,因为它们非常靠近我的位置,并且拥有快速的服务器。 (在资源管理器中对D / L几乎没有任何意义)我没有使用任何代理。

我的Crawler有大约20个线程同时从同一个站点读取。这会导致问题吗?

如何减少StreamReader.ReadToEnd DRASTICALLY?

9 个答案:

答案 0 :(得分:15)

HttpWebRequest可能需要一段时间来检测您的proxy settings。尝试将此添加到您的应用程序配置:

<system.net>
  <defaultProxy enabled="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

您可能还会看到缓冲读取时的性能略有提升,以减少对底层操作系统套接字的调用次数:

using (BufferedStream buffer = new BufferedStream(stream))
{
  using (StreamReader reader = new StreamReader(buffer))
  {
    pageContent = reader.ReadToEnd();
  }
}

答案 1 :(得分:8)

WebClient的DownloadString是HttpWebRequest的一个简单包装器,您可以尝试暂时使用它并查看速度是否提高?如果事情变得更快,你可以分享你的代码,这样我们可以看看它可能有什么问题吗?

修改

似乎HttpWebRequest遵守IE的“最大并发连接数”设置,这些网址是否在同一个域中?您可以尝试增加连接限制,看看是否有帮助?我找到了关于这个问题的this article

  

默认情况下,您无法执行更多操作   超过2-3异步HttpWebRequest(取决于   在操作系统上)。为了覆盖它   (最简单的方法,恕我直言)不要忘记   添加这个   应用程序配置中的部分   文件:

<system.net>
  <connectionManagement>
     <add address="*" maxconnection="65000" />
  </connectionManagement>
</system.net>

答案 2 :(得分:4)

我遇到了同样的问题,但当我将HttpWebRequest的Proxy参数设置为null时,它解决了这个问题。

UriBuilder ub = new UriBuilder(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri );
request.Proxy = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

答案 3 :(得分:1)

您是否尝试过ServicePointManager.maxConnections?对于类似的事情,我通常将其设置为200。

答案 4 :(得分:1)

我遇到了同样的问题,但最糟糕的是。 response =(HttpWebResponse)webRequest.GetResponse();在我的代码中 在运行更多代码之前延迟了大约10秒,之后下载使我的连接无法使用。

kurt的回答defaultProxy enabled =“false”

解决了这个问题。现在响应几乎是即时的,我可以在我的连接最高速度下载任何http文件:) 抱歉英文不好

答案 5 :(得分:1)

我发现Application Config方法不起作用,但问题仍然是代理设置。我的简单请求过去需要30秒,现在需要1秒。

public string GetWebData()
{
            string DestAddr = "http://mydestination.com";
            System.Net.WebClient myWebClient = new System.Net.WebClient();
            WebProxy myProxy = new WebProxy();
            myProxy.IsBypassed(new Uri(DestAddr));
            myWebClient.Proxy = myProxy;
            return myWebClient.DownloadString(DestAddr);
}

答案 6 :(得分:0)

谢谢大家的回答,他们帮我挖掘了正确的方向。虽然提出了更改应用程序配置文件的解决方案(因为我知道该解决方案适用于Web应用程序)并不适合我的需求,但我面临着相同的性能问题,我的解决方案如下所示:

HttpWebRequest webRequest;

webRequest = (HttpWebRequest)System.Net.WebRequest.Create(fullUrl);
webRequest.Method = WebRequestMethods.Http.Post;

if (useDefaultProxy)
{
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
    webRequest.Credentials = CredentialCache.DefaultCredentials;
}
else
{
    System.Net.WebRequest.DefaultWebProxy = null;
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
}

答案 7 :(得分:0)

为什么多线程不能解决这个问题?多线程将最小化网络等待时间,并且由于您将缓冲区的内容存储在系统内存(RAM)中,因此处理文件系统不会出现IO瓶颈。因此,您的82页下载和解析时间为82秒,应该花费15秒(假设处理器为4倍)。如果我错过了什么,请纠正我。

____下载线_____ *

下载内容

表单流

阅读内容

_________________________ *

答案 8 :(得分:0)

尝试像这样向您的请求添加cookie(AspxAutoDetectCookieSupport=1

request.CookieContainer = new CookieContainer();         
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });