公司[1]一牛人看我的代码,说我设置的timeout有误,还应该设置ReadWriteTimeout。本人很不服,于是上网查看了相关说明。
HttpWebRequest httpWebRequest = WebRequest.CreateHttp("http://www.kangry.net");
httpWebRequest.ReadWriteTimeout = ;
httpWebRequest.Timeout = ;

MSDN对ReadWriteTimeout的说明如下:

在写入由 GetRequestStream 方法返回的流时,或在读取由 GetResponseStream 方法返回的流时,会用到 ReadWriteTimeout 属性。
具体而言,ReadWriteTimeout 属性控制 Read 方法(用来读取由 GetResponseStream 方法返回的流)和 Write 方法(用来写入由 GetRequestStream 方法返回的流)的超时。
若要指定等待请求完成的时间量,请使用 Timeout 属性[2]。
MSDN对Timeout的说明如下:
Timeout 是进行后续同步请求时使用 GetResponse 方法等待响应以及 GetRequestStream 方法等待流所允许的毫秒数。 Timeout 适用于整个请求和响应,不单独对GetRequestStream 与 GetResponse 方法调用响应。 如果资源在超时期限内未返回,请求将引发 WebException,并将 Status 属性设置为 WebExceptionStatus.Timeout。
Timeout 属性必须在 GetRequestStream 或 GetResponse 方法被调用之前设置。 在调用 GetRequestStream 或 GetResponse 方法之后更改 Timeout 属性不起任何作用
Timeout 属性对使用 BeginGetResponse 或 BeginGetRequestStream 方法生成的异步请求无效[3]。

通俗一点说,Timeout设置的是从发出请求开始算起,到与服务器建立连接后收到Http响应头的时间。ReadWriteTimeout设置的是从建立连接开始,到下载数据完毕所历经的时间。
   
以下一个例子可以说明这个问题[4]。
首先是抓取的代码:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.kangry.net/Home/t1");
req.Timeout = ; //设置超时时间为5秒 Stopwatch timer = new Stopwatch();
timer.Start(); string data;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
using (StreamReader reader = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
{
data = reader.ReadToEnd();
} timer.Stop(); Console.Write(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();
return Content("休息了3秒");
} public ActionResult t3()
{
System.Threading.Thread.Sleep();
return Content("休息了7秒");
} public ActionResult t4()
{
using (var streamWriter = new StreamWriter(Response.Body, System.Text.Encoding.UTF8))
{
streamWriter.Write("hello"); //调用StreamWriter的Flush方法后,Http响应头和上面的字符串"hello"就会发送给客户端了
streamWriter.Flush(); System.Threading.Thread.Sleep();
streamWriter.Write("Kangry");
} //如果不使用StreamWriter,也可以用Response.Body.Write方法来写入数据到Http响应
//using (Response.Body)
//{
// byte[] data = System.Text.Encoding.UTF8.GetBytes("hello");
// Response.Body.Write(data, 0, data.Length); // //调用Response.Body.Flush方法后,Http响应头和字符串"hello"就会发送给客户端了
// Response.Body.Flush(); // System.Threading.Thread.Sleep(8000); // data = System.Text.Encoding.UTF8.GetBytes("Kangry");
// Response.Body.Write(data, 0, data.Length);
// Response.Body.Flush();
//} return new EmptyResult();
}

测试的结果是:

t1很快返回内容,且没有错误。
t2在3秒后也返回了内容,且没有错误。
t3在5秒后客户端抛出timeout的错误。
t4在8秒后返回内容,并没有出现错误。
根据测试结果,timeout设置的时间并不包括数据下载所耗费的时间。
MS的牛人果然牛,得多多向他学习!
 

原文链接

HttpWebRequest的timeout和ReadWriteTimeout(转载)的更多相关文章

  1. HttpWebRequest的Timeout和ReadWriteTimeout

    HttpWebRequest.Timeout在发起请求开始,如果未从远程请求的URL得到任何数据的情况下,超过Timeout后,触发超时异常 HttpWebRequest.ReadWriteTimeo ...

  2. HttpWebRequest's Timeout and ReadWriteTimeout — What do these mean for the underlying TCP connection?

    http://stackoverflow.com/questions/7250983/httpwebrequests-timeout-and-readwritetimeout-what-do-thes ...

  3. 【转载】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  4. HttpWebRequest 模拟浏览器访问网站

    最近抓网页时报错: 要么返回 The remote server returned an error: (442)要么返回: 非法访问,您的行为已被WAF系统记录! 想了想,就当是人家加了抓网页的东西 ...

  5. 【已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  6. HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  7. 利用HttpWebRequest访问WebApi

    WebApi现在越来越流行,下面给出利用HttpWebRequest访问WebApi的工具方法: 1.利用基准URL和参数字典生成完整URL /// <summary> /// 生成URL ...

  8. HttpWebRequest 基础连接已经关闭: 接收时发生错误

    HttpWebRequest request = null; Stream webStream = null; HttpWebResponse response = null; StreamReade ...

  9. C#中HttpWebRequest的GetRequestStream执行的效率太低,甚至偶尔死掉

    为了提高httpwebrequest的执行效率,查到了一些如下设置 request.ServicePoint.Expect100Continue = false; request.ServicePoi ...

随机推荐

  1. Learn How To Create Trigger In Oracle Forms

    I have written many posts related to triggers in Oracle Forms, I have given examples for Form Level ...

  2. selenium用法 (python)

    滑动到指定元素位置 browser.find_element_by_xpath("//font[text()='资产管理部经办人'][1]").location_once_scro ...

  3. EasyMvc入门教程-基本控件说明(12)栏目导航

    栏目导航一般用来显示当前页面所在的模块层级位置关系,如下图所示: 当然也有前端网站作为小栏目导航,凡是没有绝对,只要不违和就好:),下面上代码: @{ var data = new List<N ...

  4. 【React Native开发】React Native移植原生Android项目(4)

    ),React Native技术交流4群(458982758),请不要反复加群!欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文章 ...

  5. POJ-1190-生日蛋糕-DFS(深搜)-枚举-多重剪枝

    题目链接: 这个题目非常好,有难度:能够好好的多做做: #include<iostream> #include<string> #include<cstdio> # ...

  6. js 简单getByClass得封装

    function getByClass(oParent,sClass){ var elems = oParent.getElementsByTagName("*"); var ar ...

  7. 【Python】读取cvs文件报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 6: invalid start byte

    现在有文件data.csv 文件编码格式为:ANSI data.csv 1|1|1|北京市 2|1|2|天津市 3|1|3|上海市 4|1|4|重庆市 5|1|5|石家庄市 6|2|5|唐山市 7|3 ...

  8. 【Linux】 awk应用

    1  统计机器上处于不同状态的所有TCP连接的个数(TCP连接是有状态连接,包含SYN_RECV, ESTABLISHED, TIME_WAIT, FIN_WAIT0, FIN_WAIT1等多种状态, ...

  9. 用GetTickCount()计算一段代码执行耗费的时间的小例子

    var aNow,aThen,aTime:Longint; begin aThen := GetTickCount(); Sleep();//代码段 aNow := GetTickCount(); a ...

  10. PHP下最好用的富文本HTML过滤器:HTMLPurifier使用教程

    HTMLPurifier是我目前用过最好的PHP富文本HTML过滤器了,采用了白名单机制,有效杜绝了用户提交表单中的非法HTML标签,从而可以防止XSS攻击! HTMLPurifier项目地址:htt ...