HttpWebRequest的timeout和ReadWriteTimeout

Posted FrankYou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpWebRequest的timeout和ReadWriteTimeout相关的知识,希望对你有一定的参考价值。

转载:http://www.kangry.net/blog/?type=article&article_id=70

 公司[1]一牛人看我的代码,说我设置的timeout有误,还应该设置ReadWriteTimeout。本人很不服,于是上网查看了相关说明。

    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设置的是从发出请求开始算起,到与服务器建立连接的时间。ReadWriteTimeout设置的是从建立连接开始,到下载数据完毕所历经的时间。

    以下一个例子可以说明这个问题[4]

    首先是抓取的代码:    

1
2
3
4
5
6
7
8
9
HttpWebRequest req =(HttpWebRequest)WebRequest.Create("http://www.kangry.net/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更长的时间,模拟出网速很慢的样子,再把剩下的字符串发送完毕。

    代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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()
{
    //这个是伪代码,实际使用的是 t4.aspx 写的,不是asp.net mvc
    Response.Write("hello");
    Response.Flush();
    System.Threading.Thread.Sleep(8000);
    return Content(" Kangry");
}

    测试的结果是:

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

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

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

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

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

以上是关于HttpWebRequest的timeout和ReadWriteTimeout的主要内容,如果未能解决你的问题,请参考以下文章

HttpWebRequest.GetRequestStream() 超时

C# 关于Time out的简单问题

[Bug]2016-02

用asp.net c# HttpWebRequest获取网页源代码

如何在C#中终止HttpWebRequest连接?它甚至不能设置超时或readwritetimeout

HttpWebRequest请求时无法发送具有此谓词类型的内容正文。