作者unstoppable (BEN)
看板C_Sharp
标题[问题] httpwebrequest请求逾时
时间Sat Aug 22 05:49:32 2015
目前的专案是需要对多个网站抓数据下来
有将httpwebrequest包成一个方法,并使用多线程去跑
方法最後有将request abort以及response close还有设定为null
方法最前有GC.Collect();
request的keep-alive设定为false
ServicePointManager.DefaultConnectionLimit设定为512
十多个网站中,有两个常会出现逾时,其他网站不会
软体单独对这两个网站取数据不会出现
同时对十多个网站抓取数据才会发生
每个网站各自的抓取间隔皆为2秒
原本想说是不是网站本身问题,但是不全部一起抓就不会发生逾时
想请问板上前辈,还有什麽问题是可能造成这样的状况发生?
感谢
---------------------------------------------------------
补充程式码
public class MyRequest
{
string UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-TW;
rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)";
string Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, application/json,
text/javascript,text/html, application/xhtml+xml, */*";
int Timeout = 60000;
private bool CheckValidationResult(object sender, X509Certificate
certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
public List<string> Get(string Url, string Referer, CookieContainer
CC, bool UsingXMLHttpRequest, bool UsingProxy, ReturnType RT, string
HeaderName)
{
List<string> ReturnList = new List<string>();
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(Url);
if (Url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new
RemoteCertificateValidationCallback(CheckValidationResult);
req.ProtocolVersion = HttpVersion.Version10;
}
req.Referer = Referer;
req.CookieContainer = CC;
req.UserAgent = UserAgent;
req.Accept = Accept;
req.Timeout = Timeout;
req.Headers["Accept-Language"] = "zh-TW";
req.AutomaticDecompression = DecompressionMethods.GZip;
req.KeepAlive = false;
if (UsingXMLHttpRequest)
{
req.Headers["X-Requested-With"] = "XMLHttpRequest";
}
if (UsingProxy)
{
req.Proxy = Proxy;
}
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
if (RT == ReturnType.ResponseContent)
{
string str = sr.ReadToEnd();
ReturnList.Add(str);
}
else if (RT == ReturnType.ResponseUrl)
{
string str = res.ResponseUri.ToString();
ReturnList.Add(str);
}
else if (RT == ReturnType.ResponseHeader)
{
string HeaderStr = string.Empty;
if (HeaderName.Contains(","))
{
string[] HNarray = HeaderName.Split(',');
for (int i = 0; i < HNarray.Length; i++)
{
HeaderStr += res.GetResponseHeader(HNarray[i]);
if (i != HNarray.Length - 1)
{
HeaderStr += "|";
}
}
ReturnList.Add(HeaderStr);
}
else
{
HeaderStr = res.GetResponseHeader(HeaderName);
ReturnList.Add(HeaderStr);
}
}
else if (RT == ReturnType.All)
{
string str1 = sr.ReadToEnd();
string str2 = res.ResponseUri.ToString();
ReturnList.Add(str1);
ReturnList.Add(str2);
string HeaderStr = string.Empty;
if (HeaderName.Contains(","))
{
string[] HNarray = HeaderName.Split(',');
for (int i = 0; i < HNarray.Length; i++)
{
HeaderStr += res.GetResponseHeader(HNarray[i]);
if (i != HNarray.Length - 1)
{
HeaderStr += "|";
}
}
ReturnList.Add(HeaderStr);
}
else
{
HeaderStr = res.GetResponseHeader(HeaderName);
ReturnList.Add(HeaderStr);
}
}
sr.Close();
res.Close();
req.Abort();
return ReturnList;
}
public enum ReturnType
{
ResponseContent,
ResponseUrl,
ResponseHeader,
All
}
}
个人将上面方法包成一个DLL
专案本身使用backgroundwork来跑
Dowork内使用Get()取资料
结束後thread.sleep(2000);
之後进到RunWorkerCompleted再重新呼叫BGW.RunWorkerAsync();
----------------------------------------------------------
更新进度
怎样修改都没有好转
原本测试的平台是Server2003 X86 种花固I
转移到Win7 X64 种花浮动
什麽问题都没有了....
在Server2008 X64上也都没有问题
专案编辑是32位元的
也看过工作管理员是*32在执行
想请问这样可能会是什麽问题?
对了,专案是.net 4.0
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.240.231.238
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1440193774.A.9B5.html
1F:→ fo40225: 有完整的程式码吗? 这样比较好找问题 08/22 08:24
2F:→ fo40225: 然後 不要呼叫GC.Collect() 你呼叫这个 他要把所有的线程 08/22 08:30
3F:→ fo40225: 挂起 很伤效能 08/22 08:30
4F:→ fo40225: 也不要把物件设为null 这样会让物件被GC的时间延後 08/22 08:31
5F:→ fo40225: .net的最佳记忆体管理方式就是有IDisposable时用using 08/22 08:33
6F:→ fo40225: 然後其他的不要管 把物件设为null在C++才是呼叫解构子 08/22 08:35
7F:→ fo40225: C#中没有意义 08/22 08:35
8F:→ fo40225: 如果你是.net4.5以上 你可以试试用HttpClient 08/22 08:37
※ 编辑: unstoppable (111.240.231.238), 08/22/2015 15:14:21
9F:→ fatrabitree: C++设为null也没有呼叫解构子就是... 08/22 15:24
10F:→ fo40225: 那就是我误解了 抱歉误导了 08/22 21:08
11F:→ fo40225: backgroundworker是设计拿来CPU-bound 别拿来IO 08/22 21:31
12F:→ fo40225: 试试 (HttpWebResponse)await req.GetResponseAsync(); 08/22 21:31
13F:→ fo40225: 有没有可能是频宽吃紧 导致60秒载不完? 08/22 21:32
14F:→ fo40225: 不然就是线程太多 来不及反应 08/22 21:32
感谢fo细心回应
用BGW主要是因为更新UI界面太方便了~XD(明明就是自己懒得写thread委派)
频宽应该不会是主要的原因,数据都是1~2X K的大小
目前看线程同时间最多7个BGW在跑
GetResponseAsyn这个我研究下,第一次看到
※ 编辑: unstoppable (111.240.231.238), 08/22/2015 23:52:32
※ 编辑: unstoppable (111.240.231.238), 08/23/2015 07:17:40