12

我请求了 100 页,全部 404。我写了

    {
    var s = DateTime.Now;
    for(int i=0; i < 100;i++)
        DL.CheckExist("http://google.com/lol" + i.ToString() + ".jpg");
    var e = DateTime.Now;
    var d = e-s;
        d=d;
        Console.WriteLine(d);
    }

static public bool CheckExist(string url)
{
    HttpWebRequest wreq = null;
    HttpWebResponse wresp = null;
    bool ret = false;

    try
    {
        wreq = (HttpWebRequest)WebRequest.Create(url);
        wreq.KeepAlive = true;
        wreq.Method = "HEAD";
        wresp = (HttpWebResponse)wreq.GetResponse();
        ret = true;
    }
    catch (System.Net.WebException)
    {
    }
    finally
    {
        if (wresp != null)
            wresp.Close();
    }
    return ret;
}

两次运行显示它需要 00:00:30.7968750 和 00:00:26.8750000。然后我尝试了Firefox并使用以下代码

<html>
<body>
<script type="text/javascript">
for(var i=0; i<100; i++)
    document.write("<img src=http://google.com/lol" + i + ".jpg><br>");
</script>

</body>
</html>

使用我的补偿时间并计算它大约是 4 秒。4 秒比我的应用快 6.5-7.5。我计划扫描数千个文件,因此花费 3.75 小时而不是 30 分钟将是一个大问题。我怎样才能使这段代码更快?我知道有人会说 Firefox 缓存了图像,但我想说 1)它仍然需要检查远程服务器的标头以查看它是否已更新(这是我希望我的应用程序执行的操作)2)我不是接收正文,我的代码应该只请求标题。那么,我该如何解决呢?

4

8 回答 8

52

我注意到HttpWebRequest第一个请求挂起。我做了一些研究,似乎正在发生的事情是请求正在配置或自动检测代理。如果你设置

request.Proxy = null;

在 Web 请求对象上,您可能能够避免初始延迟。

使用代理自动检测:

using (var response = (HttpWebResponse)request.GetResponse()) //6,956 ms
{
}

没有代理自动检测:

request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse()) //154 ms
{
}
于 2009-06-01T17:01:11.830 回答
4

将您的代码更改为异步 getresponse

public override WebResponse GetResponse() {
    •••
    IAsyncResult asyncResult = BeginGetResponse(null, null);
    •••
    return EndGetResponse(asyncResult);
}

异步获取

于 2009-04-16T00:55:30.027 回答
2

可能 Firefox 一次发出多个请求,而您的代码一个一个地执行它们。也许添加线程会加快你的程序。

于 2009-04-16T00:40:59.390 回答
1

答案是仅将 HttpWebRequest/HttpWebResponse 更改为 WebRequest/WebResponse。这解决了问题。

于 2009-10-16T20:52:05.687 回答
0

您是否尝试在部署代码的机器上的 IE 中打开相同的 URL?如果它是 Windows Server 机器,那么有时是因为您请求的 url 不在 IE 的安全站点列表中(HttpWebRequest 可以使用)。你只需要添加它。

你有更多可以发布的信息吗?我做过类似的事情,之前遇到过 HttpWebRequest 的大量问题。都是独一无二的。所以更多信息会有所帮助。

顺便说一句,在这种情况下,使用异步方法调用它并没有真正的帮助。它不会缩短下载时间。它只是不会阻塞你的调用线程而已。

于 2009-04-16T01:31:06.213 回答
0

完成后关闭响应流,因此在您的 checkExist() 中,在 wresp = (HttpWebResponse)wreq.GetResponse() 之后添加 wresp.Close();

于 2010-08-18T16:07:27.013 回答
0

好的,如果您获得所有网页的状态代码 404,那么这是由于未指定凭据。所以你需要添加

wreq.Credentials = CredentialCache.DefaultCredentials;

然后您可能还会遇到状态代码= 500,因为您需要指定用户代理。看起来像下面的行

wreq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0";

“默认情况下,WebClient 实例不发送可选的 HTTP 标头。如果您的请求需要可选标头,则必须将标头添加到 Headers 集合中。例如,要在响应中保留查询,您必须添加用户代理标头。此外,如果缺少用户代理标头,服务器可能会返回 500(内部服务器错误)。”

参考:https ://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.110).aspx

要提高 HttpWebrequest 的性能,您需要添加

wreq.Proxy=null

现在代码将如下所示:

 static public bool CheckExist(string url)
{
    HttpWebRequest wreq = null;
    HttpWebResponse wresp = null;
    bool ret = false;

try
{
    wreq = (HttpWebRequest)WebRequest.Create(url);
    wreq.Credentials = CredentialCache.DefaultCredentials;
    wreq.Proxy=null;
    wreq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0";
    wreq.KeepAlive = true;
    wreq.Method = "HEAD";
    wresp = (HttpWebResponse)wreq.GetResponse();
    ret = true;
}
catch (System.Net.WebException)
{
}
finally
{
    if (wresp != null)
        wresp.Close();
}
return ret;

}

于 2017-04-17T14:27:16.943 回答
0

设置 cookie 很重要,您必须AspxAutoDetectCookieSupport=1像这样添加代码

 req.CookieContainer = new CookieContainer();         
 req.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });
于 2020-11-19T10:49:21.870 回答