打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
webrequest的timeout属性作用范围

使用c#进行抓取网页信息时,使用httpwebrequest进行抓取,通常都会自定义设置一个timeout超时值,如果不设置的话,系统默认的超时值比较高,往往长时间的等待没有意义,不如手动设置一个比较小的值,例如5秒,这样5秒内如若还连不上,则可以考虑重新建立连接或者做其他事情。

不过使用中发现一个奇怪的现象,就是对一个页面的抓取,已经超过了设置的timeout值了,既没有抛出异常也没有完成数据抓取,仍需要等待非常长的时间后才报告一个错误。仔细查看了关于 HttpWebRequest.Timeout 的解释:

Timeout 是进行后续同步请求时使用 GetResponse 方法等待响应以及 GetRequestStream 方法等待流所允许的毫秒数。 Timeout 适用于整个请求和响应,不单独对 GetRequestStream 与 GetResponse 方法调用响应。 如果资源在超时期限内未返回,请求将引发 WebException,并将 Status 属性设置为 WebExceptionStatus.Timeout。

Timeout 属性必须在 GetRequestStream 或 GetResponse 方法被调用之前设置。 在调用 GetRequestStream 或 GetResponse 方法之后更改 Timeout 属性不起任何作用

Timeout 属性对使用 BeginGetResponse 或 BeginGetRequestStream 方法生成的异步请求无效。

觉得timeout的作用域是控制与目标服务器建立连接的超时时间,也就是说,当我们和服务器能在规定的timeout时间内建立tcp连接,便不会异常,而后,页面数据的下载很慢的过程不在timeout的范围内。这就导致了该下载过程漫长而无果。为了验证这个猜想,我做了几个页面,分别在里面设置System.Threading.Thread.Sleep(n)方法来人为延时。

首先是抓取的代码:

  
  
HttpWebRequest req =(HttpWebRequest)  WebRequest.Create("http://lixin.me/t1");  req.Timeout = 5000; //设置超时时间为5秒  Stopwatch timer = new Stopwatch();  timer.Start();  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  StreamReader reader = new StreamReader(resp.GetResponseStream());  string data = reader.ReadToEnd();  timer.Stop();  textBox1.AppendText(data + "\r\n"+timer.Elapsed.TotalSeconds.ToString()+"\r\n");

其中我做了几个页面,分别是”t1″、“t2”、“t3”、“t4”。

其中t1页面直接返回文本内容,用作基础对照。

t2页面设置了一个延时,但是延时时间在超时的范围内。

t3页面设置了一个延时,但是延时时间超过抓取程序的timeout时间。

t4页面首先是先往客户端发送一部分内容,然后延时一段比timeout更长的时间,模拟出网速很慢的样子,再把剩下的字符串发送完毕。

代码如下:

  
  
public ActionResult t1()    {      return Content("直接返回内容。");    }    public ActionResult t2()    {      System.Threading.Thread.Sleep(3000);      return Content("休息了3秒");    }    public ActionResult t3()    {      System.Threading.Thread.Sleep(7000);      return Content("休息了7秒");    }    public ActionResult t4()    {      Response.Write("hello");      Response.Flush();      System.Threading.Thread.Sleep(8000);      return Content(" lixin");    }

测试的结果是:

t1很快返回内容,且没有错误。

t2在3秒后也返回了内容,且没有错误。

t3在5秒后客户端抛出timeout的错误。

t4在8秒后返回内容,并没有出现错误。

根据测试结果,timeout设置的时间并不包括数据下载所耗费的时间。

那么要在规定的时间内完成下载数据任务否则就重新开始呢?这就得使用HttpwebRequest另一个属性值了: ReadWriteTimeout

在写入由 GetRequestStream 方法返回的流时,或在读取由 GetResponseStream 方法返回的流时,会用到 ReadWriteTimeout 属性。

具体而言,ReadWriteTimeout 属性控制 Read 方法(用来读取由 GetResponseStream 方法返回的流)和 Write 方法(用来写入由 GetRequestStream 方法返回的流)的超时。

若要指定等待请求完成的时间量,请使用 Timeout 属性。

根据文档描述,这个属性的设置就是设置读取数据流的超时时间了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法...
利用C#编写一个简单的抓网页应用程序
使用C#的HttpWebRequest模拟登陆访问人人网
HttpWebRequest和HttpWebResponse用法小结
C#通过WebClient/HttpWebRequest实现http的post/get方法
C#通过GET/POST方式发送Http请求
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服