• HttpWebRequest的timeout和ReadWriteTimeout(转载)


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

    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 = 5000; //设置超时时间为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 + "
    " + timer.Elapsed.TotalSeconds.ToString() + "
    ");

    其中我做了几个页面,分别是”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()
    {
        using (var streamWriter = new StreamWriter(Response.Body, System.Text.Encoding.UTF8))
        {
            streamWriter.Write("hello");
    
            //调用StreamWriter的Flush方法后,Http响应头和上面的字符串"hello"就会发送给客户端了
            streamWriter.Flush();
    
            System.Threading.Thread.Sleep(8000);
            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的牛人果然牛,得多多向他学习!
     

      

    原文链接

  • 相关阅读:
    友盟冲突解决com.umeng.weixin.handler.UmengWXHandler cannot be cast to com.umeng.socialize.handler.UMWXHandler
    插入mysql失败,因为java数据类型是个实体类,加上.id就好了
    app升级注意事项version
    关于ehcache缓存中eternal及timeToLiveSeconds和timeToIdleSeconds的说明
    WinFom解决最小化最大化后重绘窗口造成闪烁的问题
    Redis 发布订阅
    Redis 发布订阅
    ASPxGridView
    ASPxGridView
    C#-WebRequest 超时不起作用
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10823235.html
Copyright © 2020-2023  润新知