当我把它放在一个方法中时,C#HttpWebResponse.GetResponse()会挂起

时间:2017-08-08 14:03:12

标签: c# http httpwebrequest

我想在网站上搜索4位数字,并在页面上提取包含此数字的链接。 以下代码工作正常:

List<KeyValuePair<int, string>> urls = new List<KeyValuePair<int, string>>();
for (int index = 3000; index < 4000; index++) {
    string url = "http://www.myurl.com/page?q=" + index.ToString();
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    if (response.StatusCode == HttpStatusCode.OK) {
        Stream receiveStream = response.GetResponseStream();
        StreamReader readStream = null;

        if (response.CharacterSet == null) {
            readStream = new StreamReader(receiveStream);
        } else {
            readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
        }

        string itemurl = "";
        while (!readStream.EndOfStream) {
            string ln = readStream.ReadLine();
            int start = ln.IndexOf("https://www.myurl.com/" + index.ToString());
            if (start > -1) {
                int stop = ln.IndexOf(".htm\"", start) + 4;
                itemurl = ln.Substring(start, stop - start);
                Console.Write(index + ", ");
                urls.Add(new KeyValuePair<int, string>(index, itemurl));
                break;
            }
        }
        response.Close();
        readStream.Close();
    }
}

但是,如果我将检查部分(循环中的所有内容)放入一个返回url的方法中:

string GetUrl(int index) {
..
        //urls.Add(new KeyValuePair<int, string>(index, itemurl)); is replaced by:
        return itemurl;
..
    return "";
}

然后我在循环中调用该方法:

    List<KeyValuePair<int, string>> urls = new List<KeyValuePair<int, string>>();
    for (int index = 3000; index < 4000; index++) {
        string itemurl = GetUrl(index);
        if(itemurl != "") urls.Add(new KeyValuePair<int, string>(index, itemurl));
    }

程序将在找到2个网址后完全挂起,我看不出为什么会发生这种情况。挂起将发生在request.GetResponse(); 我试图将Timeout设置为500毫秒,捕获异常并稍后重试,但我仍然不会得到响应。 我也可以搜索其他数字,结果是一样的。找到两个网址后它会挂起。我试图在.NET 3.5,4.0,4.5,4.6之间切换Release或Debug,结果是一样的。我正在运行Windows 10,但我也在运行8.1和XP VM的远程计算机上尝试过它并获得了相同的效果。

如果我没有将它放在一个单独的方法中,那么它会在不到一分钟的时间内检查1000个数字。

我开始对这个问题感到非常不安,所以任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

经过几个小时的挣扎,我找到了导致问题的原因,所以我会分享解决方案。

问题是,当我返回一个url时,我没有调用response.Close()方法,因此它仍在使用资源。在返回之前调用此方法解决了问题。 另一种解决方案是将代码放入使用块中,例如:

using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()){
..
}