C# 中 Timeout 的处理

前言

最近在项目中要实现一个功能,是关于 Timeout 的,主要是要在要在 TCP 连接建立的时间 和 整个请求完成的时间,在这两个时间层面上,如果超出了设置的时间,就抛出异常,程序中断。

研究了一下项目的代码中,发现在使用HTTP协议,发送请求时,主要用的是微软的 Microsoft.Net.HttpWebRequest 这个类来发起请求和接收请求的。当时我隐约记得这个类怎么有点熟悉呀,好像还有 WebRequstHttpClient 这两个把,还没开始真正开始去了解TimeoutHttpWebRequest中 如何实现的,我先去看了看这三者到底有何不同?

WebRequest , HttpWebRequest , HttpClient

WebRequest 是 一个抽象类,是HttpWebRequest 的父类。是.NET中请求和获取网络中的数据的一个类。

HttpWebRequestWebRequest 的一个实现,不仅对WebRequest中的属性和方法进行了支持,而且还有额外的方法通过Http协议来和服务端交互。

上面那两个现在在微软官方文档上都不推荐使用了,

现在所推荐的是 HttpClient 。由于项目中遗留之前使用的是HttpWebRequest,所以就在原来的基础上进行实现,何况的是在HttpClient中没有找到TCP连接建立的时间属性的设定。

HttpClient 优点自不必多说:

  • 连接池
  • 一次初始化,整个生命周期的重用
  • 和 .Net Core 的融合
  • 以及性能的提升等等

虽然说性能可能提升了,如果你这样用,那也是凉凉

using(HttpClient clinet = new HttpClient())
{
var result = await client.GetAsync("http://aspnetmonsters.com");
Console.WriteLine(result.StatusCode);
}

用完 Using 后,调用了IDispose 接口。那下次还是会重新初始化

这样使用就没问题了

private static HttpClient Client = new HttpClient();

Timeout, ReadWriteTimeout

也可能是我英文的理解能力有点差,在开始我就注意到这个类里面的这两个属性,但是我如何也无法和 TCP 建立前所用的连接时间 与 请求完成的时间联系起来。微软官方文档解释如下:

Timeout

Timeout is the number of milliseconds that a subsequent synchronous request made with the GetResponse method waits for a response, and the GetRequestStream method waits for a stream. The Timeout applies to the entire request and response, not individually to the GetRequestStream and GetResponse method calls. If the resource is not returned within the time-out period, the request throws a WebException with the Status property set to WebExceptionStatus.Timeout.

The Timeout property has no effect on asynchronous requests made with the BeginGetResponse or BeginGetRequestStream method.

ReadWriteTimeout:

The ReadWriteTimeout property is used when writing to the stream returned by the GetRequestStream method or reading from the stream returned by the GetResponseStream method.

Specifically, the ReadWriteTimeout property controls the time-out for the Read method, which is used to read the stream returned by the GetResponseStream method, and for the Write method, which is used to write to the stream returned by the GetRequestStream method.

设置其实是很方便的,如下所示:

HttpWebRequest request = (HttpWebRequest)WebRequest.Creat("<your url>");

//Set timeout to 1s
request.Timeout = 1000; //Set ReadWriteTimeout to 3000
request.ReadWriteTimeout = 3000; HttpWebResponse response = (HttpWebResponse)request.GetResponse();

WebClient.Exception.Timeout 和 OperationCanceledException

最后在捕捉异常的时候,发现了一个很奇怪的地方,就是使用两段代码,却抛出了不同的异常,

第一段代码:

HttpWebRequest request = (HttpWebRequest) WebRequest.Create("https://www.alibabacloud.com");
request.Timeout = 5000;
HttpWebResponse response = (HttpWebResponse) request.GetResponse(); HttpWebRequest request2 = (HttpWebRequest) WebRequest.Create("https://www.cnblogs.com");
request2.Timeout = 1;
HttpWebResponse response2 = (HttpWebResponse) request2.GetResponse(); //Exception
/*
Unhandled Exception: System.Net.WebException: The operation has timed out.
at System.Net.HttpWebRequest.GetResponse()
*/

第二段

HttpWebRequest request = (HttpWebRequest) WebRequest.Create("https://www.alibabacloud.com");
request.Timeout = 5000;
HttpWebResponse response = (HttpWebResponse) request.GetResponse(); request = (HttpWebRequest) WebRequest.Create("https://www.cnblogs.com");
request.Timeout = 1;
response = (HttpWebResponse) request.GetResponse(); //Exception
/*
Unhandled Exception: System.OperationCanceledException: The operation was canceled.
at System.Net.HttpWebRequest.GetResponse()
*/

初步估计的原因是,Http 请求中 Keep-Alive的关系,还有一个可能是 Timeout 的这个说明:

**The Timeout applies to the entire request and response, not individually to the GetRequestStream and GetResponse method calls. ** 然而具体的还没搞清楚,还需要去验证。

后记

其实,设置这两个属性你可能只需要找到文档,分分钟就可以搞定,但是我为什么会在这个过程遇到这些问题呢?一方面是对于C# 中网络请求的不熟悉,其次是找个时间,把以前的代码需要重构一下了,比如把HttpWebRequest 换成 HttpClient 等等。也让我加深了对Http协议的理解。

C# .net 中 Timeout 的处理及遇到的问题的更多相关文章

  1. Angular JS中$timeout的用法及其与window.setTimeout的区别

    $timeout的用法 angular.js的$timeout指令对window.setTimeout做了一个封装,它的返回值是一个promise对象.当定义的时间到了以后,这个promise对象就会 ...

  2. 改变CTS测试中timeout时间

    关键类: JarHostTest.java——>目录:%SOURCE_ROOT%/cts/tools/tradefed-host/src/com/android/cts/tradefed/tes ...

  3. shell中timeout实现

    第一种 function timeout() { waitsec=$SLEEP_TIME ( $* ) & pid=$! ( sleep $waitsec && kill -H ...

  4. AngularJS中$timeout和$interval的用法详解

    1. 先将$interval,$timeout,作为参数注入到controller中,例如rds.controller('controllerCtrl', ['app', '$scope','$htt ...

  5. [转]AngularJS中$timeout和$interval的用法详解

    本文转自:http://www.cnblogs.com/moli-/p/5827618.html 1. 先将$interval,$timeout,作为参数注入到controller中,例如rds.co ...

  6. 关于angular JS 中$timeOut 的一些不正常情况下的$destory

    最近项目中存在的问题头疼脑热了好一会. 我先简单说明下问题是由,使用$timeOut循环调用的时候由于页面存在异步加载会出现反复执行循环反复调用$timeOut,怎么清除跳出循环都不管用.于是查到了如 ...

  7. python 在爬虫中timeout设置超时有什么作用

    是为了防止url不可访问,或者响应速度太慢而造成的时间浪费. 比如,你要爬取1000个网站,如果有100个需要30s才能返回数据,你等待他们返回的话就需要3000s了,如果你设置10s超时,那么就能知 ...

  8. JavaScript 的setTimeout 和Angular中的$timeout的區別

    JavaScript中setTimeout返回值类型和意义说明: 1.setTimeout :暂停指定的毫秒数后执行指定的代码,返回值是id标识,这个id的意义就是通过clearTimeout来清理暂 ...

  9. golang中mysql建立连接超时时间timeout 测试

    本文测试连接mysql的超时时间. 这里的"连接"是建立连接的意思. 连接mysql的超时时间是通过参数timeout设置的. 1.建立连接超时测试 下面例子中,设置连接超时时间为 ...

随机推荐

  1. [九省联考2018]IIIDX

    题目描述 这一天,Konano接到了一个任务,他需要给正在制作中的游戏<IIIDX>安排曲目的解锁顺序.游戏内共有n首曲目 ,每首曲目都会有一个难度d,游戏内第i首曲目会在玩家Pass第t ...

  2. Docker:Docker 性质及版本选择 [三]

    一.Docker的性质 Docker的组成其实很简单.你需要搭建registry,专属于你自己的私有仓库,然后就是docker的镜像和docker的容器.Docker的镜像,就类似与windos的系统 ...

  3. vue 开发微信小程序

    介绍 mpvue (github 地址请参见)是一个使用 Vue.js 开发小程序的前端框架.框架基于 Vue.js 核心,mpvue 修改了 Vue.js的 runtime 和 compiler 实 ...

  4. 我的 Erdos 数是 4

    我的 Erdos 数是 4. 呵呵. 图书馆开通了一个月的 mathscinet 数据库查询. 本来想买个 pde 的最新进展, 结果不能查询, 就算了.

  5. 定期清理WordPress的文章修订版本

    当WordPress编辑或修改文章时会自动保存生成一个修订版本,默认是每分钟1次.方便恢复早先撰写的版本.不过时间一长就会产生大量的冗余数据,加重服务器负担,拖慢数据加载.当所有发布的文章都已更新到最 ...

  6. 边框回归(bounding-Box regression)

    转自:https://blog.csdn.net/zijin0802034/article/details/77685438 为什么要边框回归? 什么是边框回归? 边框回归怎么做的? 边框回归为什么宽 ...

  7. webpack学习笔记——sourcemap(使用webpack打包的项目如何调试代码)

    [webpack]devtool里的7种SourceMap模式是什么鬼? 里面详细介绍了7种模式的区别,和建议使用. webpack sourcemap 选项多种模式的一些解释 两篇文章大同小异,第一 ...

  8. Codeforces 1097G

    根本想不到 CF1097G 题意 给出一棵树,定义f(S)为用最少的边连通点集$ S$的边数 求$ \sum\limits f(S)^k$ $ n \leq 10^5 k \leq 200$ 题解 假 ...

  9. torch.utils.data.DataLoader对象中的迭代操作

    关于迭代器等概念参考:https://www.cnblogs.com/zf-blog/p/10613533.html 关于pytorch中的DataLoader类参考:https://blog.csd ...

  10. SQL Server Change Tracking

    1 概述 “更改跟踪”和“变更数据捕获”捕获和记录用户表的DML更改(插入.更新和删除操作),为某些有特殊需求的应用程序服务. 1.1 更改跟踪 更改跟踪捕获表的数据行更改这一行为,但不会捕获更改的具 ...