【问题标题】:WebClient is very slowWebClient 很慢
【发布时间】:2011-10-22 18:30:11
【问题描述】:

我的 Webclient 有问题。

速度很慢。从一个网站下载字符串大约需要 3-5 秒。 我没有任何网络问题。

这是我修改后的 WebClient。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace StatusChecker
{
    class WebClientEx: WebClient
    {
        public CookieContainer CookieContainer { get; private set; }

        public WebClientEx()
        {
            CookieContainer = new CookieContainer();

            ServicePointManager.Expect100Continue = false;
            Encoding = System.Text.Encoding.UTF8;

            WebRequest.DefaultWebProxy = null;
            Proxy = null;
        }

        public void ClearCookies()
        {
            CookieContainer = new CookieContainer();
        }

        protected override WebRequest GetWebRequest(Uri address)
        {

            var request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                (request as HttpWebRequest).CookieContainer = CookieContainer;
            }
            return request;
        }
    }
}

更新: 在 Wireshark 中,我看到单个 DownladString 正在发送和接收数千个数据包。

【问题讨论】:

  • WebClient 不是特别慢,问题肯定出在其他地方……也许你下载的网站很慢?
  • 您应该尝试使用像 WireShark 这样的流量记录器来确定延迟是否确实在单个请求和响应帧之间(由网络/服务器减速引起)或者是因为客户端代码行为不端并发送出去请求过多或某些此类逻辑错误。
  • 还在循环中执行多个下载以“预热”该过程(例如消除程序集的加载)。
  • 更新:在wireshark中,我看到单个DownladString正在发送和接收数千个数据包。请帮帮我。
  • 如果您要下载的内容真的很大,这是您应该期待的。如果手动下载网址,有多大?

标签: c# .net networking httpwebrequest webclient


【解决方案1】:

这里可能有两个问题(我之前在自己的程序中也注意到了):

  • 第一个请求花费了异常长的时间:这是因为WebRequest 在默认情况下会在第一次启动时检测并加载代理设置,这可能需要相当长的时间。要阻止这种情况,只需将代理属性 (WebRequest.Proxy) 设置为 null,它将绕过检查(前提是您可以直接访问互联网)
  • 一次下载的项目不能超过 2 个:默认情况下,您只能同时打开 2 个 HTTP 连接。要更改此设置,请将ServicePointManager.DefaultConnectionLimit 设置为更大的值。我通常将其设置为int.MaxValue(只要确保您不会向拥有 1,000,000 个连接的主机发送垃圾邮件)。

【讨论】:

  • 就我而言,这不是正确的答案。您可以看到我已经将代理设置为空。而且我不会同时下载 2 个项目。正如在我的帖子中添加的那样,在 Wireshark 中,我可以看到我的应用程序每个下载字符串都会发送和接收数千个数据包。 String 是简单的网站,例如 google.com。
  • 如果它不是异常慢(意味着连接在保持连接关闭的情况下具有大致相同的速度),那么它应该正常工作。执行握手、发出请求、等待服务器创建响应、然后读取响应都需要时间。
  • 你能告诉我更多关于那些保持活力的信息吗?为什么我的应用会发送数千个数据包?
  • 一个packet代表一个数据。文件或 HTML 页面通常由一个大文件组成,由于 Internet 协议的设计,该文件太大而无法一次性传输。出于这个原因,我们需要将一个大文件(几乎任何超过 1kB 的文件)拆分为许多部分,以将它们作为流发送。每个部分都是一个数据包。你看到的完全正常。 Keep alives 加速重新连接,保持连接(到特定服务器)处于活动状态,这样我们就不必在每个新请求(到该特定服务器)上握手。
  • 我只连接到一台服务器。怎么养活?
【解决方案2】:

如果与正在检查的初始代理设置有关,有几个选项:

  1. 禁用 Internet Explorer 中的自动代理检测设置
  2. 将代理设置为空:

    WebClient.Proxy = null

  3. 在应用程序启动时将默认 webproxy 设置为 null:

    WebRequest.DefaultWebProxy = null;

在较旧的 .NET 代码中,您以前不会设置为 null,而是这样编写(但现在首选 null):

webclient.Proxy = GlobalProxySelection.GetEmptyWebProxy();

【讨论】:

    【解决方案3】:

    也许它会对某人有所帮助。一些 Web 服务支持压缩(gzip 或其他)。因此,您可以为您的请求添加 Accept-Encoding 标头,然后为 Web 客户端实例启用 automatic decompression。 Chrome 就是这样工作的。

    【讨论】:

      猜你喜欢
      • 2016-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多