WebClient 很慢

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中我看到单个DownloadString正在发送和接收数千个数据包。


4
WebClient并不特别慢,问题必须出在其他地方...也许你从中下载的网站很慢? - Thomas Levesque
1
你应该尝试使用像WireShark这样的流量记录器来确定延迟是否确实发生在单个请求和响应帧之间(由网络/服务器减速引起),还是因为客户端代码行为不当,发送了过多的请求或出现了某些逻辑错误。 - D. A. Terre
更新: 在wireshark中,我看到单个DownloadString正在发送和接收数千个数据包。 请帮助我。 - Hooch
发送和接收大量数据包可能只是由于流媒体,本身并不意味着出现任何问题。 - Quintin Robinson
1
如果你下载的内容非常大,这就是你应该预期的。如果你手动下载URL,它有多大? - Jacob
显示剩余2条评论
3个回答

31

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

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

1
在我的情况下,这不是正确的答案。您可以看到我已将代理设置为 null。而且我没有同时下载2个项目。我还在帖子中添加了这一点,在Wireshark中,我可以看到我的应用程序在每个下载字符串中发送和接收数千个数据包。字符串就像简单的网站google.com。 - Hooch
你能告诉我更多关于那些保持连接的信息吗?为什么我的应用程序会发送成千上万个数据包? - Hooch
我只连接一个服务器。如何保持连接? - Hooch
@Hooch 迟到总比不到好,但如果你使用一个 WebClient 并在多个请求中保持对象活动状态,它会自动执行该操作。 - Aidiakapi
@Hooch 如果你没有指定不保持连接,那么它会自动保持连接的 :) - Aidiakapi
显示剩余3条评论

2

如果与初始代理设置有关,则有几个选项:

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

    WebClient.Proxy = null

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

    WebRequest.DefaultWebProxy = null;

在旧的.NET代码中,您可以使用以下代码(但现在推荐使用null):

webclient.Proxy = GlobalProxySelection.GetEmptyWebProxy();

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接