我想在网站上搜索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个数字。
我开始对这个问题感到非常不安,所以任何帮助都会非常感激。
答案 0 :(得分:0)
经过几个小时的挣扎,我找到了导致问题的原因,所以我会分享解决方案。
问题是,当我返回一个url时,我没有调用response.Close()
方法,因此它仍在使用资源。在返回之前调用此方法解决了问题。
另一种解决方案是将代码放入使用块中,例如:
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()){
..
}