C#中的废物 WebRequest

2018-09-10 17:13:29 +08:00
 xiangyuecn

吐槽+骂街贴:吃屎的.net ,一个基本的 http 请求也搞的这么难用,因为一个功能放弃一门(暂且叫语言吧)。

一直用的 WebRequest,直到今天...

1. 完全没法根据需要设定超时

有 Timeout、ReadWriteTimeout ?没用的!看 MSDN 的解释:

https://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest.timeout(v=vs.110).aspx 域名系统 (DNS) 查询可能需要最多 15 秒钟才能返回或超时。 如果您的请求包含需要解析的主机名,并设置 Timeout 为一个值小于 15 秒,可能需要 15 秒或更长之前 WebException 引发来指示您的请求超时

至少包含一个隐藏的不可控因素,也就是说你没法简单的完全控制请求超时,Timeout 完全是摆设,TMD 的.net 侮辱了 Timeout 这个单词。

ReadWriteTimeout 算是摆设吧,是数据流 read、write 调用超时,意思相近于发送一个直接后等待下一个字节的时间不能超过这个,并非 100%读取完数据和发送完数据的超时控制。然后他默认的 5 分钟完全是废物设定,没错,废物。( java 的 HttpURLConnection 有个设定好像也是如此吧记得)。

没有 ConnectTimeout 选项。没有 ConnectTimeout 选项。没有 ConnectTimeout 选项。(根源所在)

2. 曲线救国 BeginGetRequestStream

使用异步的发送数据流可以变相实现 ConnectTimeout,拿到请求数据流代表已经连上了服务器。

但 GET、HEAD 明确不支持获取 RequestStream。意思就是说 GET 请求你往请求体里面塞东西,.net 就把你写的渣渣代码给干掉,从源头上拒绝你的操作。看到这个逼玩意怎么一个火字了得。

劳资发个请求你还要管我的 method 是什么!

GET 没法拿到请求数据流,GET 没法拿到请求数据流,GET 没法拿到请求数据流。(已经过了底线)

WebRequest 没法实现

比如:严格控制一个 GET 请求耗时在 3 秒以内,超过时间就超时,用来检测 url 是否可以访问。遇到类似 www.google.com 就,,,呵呵了。POST 用 BeginGetRequestStream 没这个问题

要自己实现整体的请求超时功能,他不支持,开个线程也好,开个计时器也好。

GET 不让发请求体,可能很科学,但遇上真不爽

我只是想拿一下发送请求的数据流而已,并非真要往 stream 里面塞数据。

放弃.net

用第三方库解决此类问题?关键是框架给的功能已经能满足 98%的功能了,卡在了这 2%必须实现的功能上而已。用第三方的是不可能的,这辈子都不可能为了这么小小的功能 load 一个 100M 的第三方库的。

so..用 java 吧,或者 php 也行,至少写一个简单的网络请求没这糟心。遇到忍无可忍的地方就换个语言,不是针对.net ,我是说所有的语言!

(文中 C#语言==.net 框架 并非你异议中的 C#语言!=.net 框架,不服去车上拿刀,拿紧)

10544 次点击
所在节点    程序员
84 条回复
ruatyy
2018-09-10 17:17:49 +08:00
兄弟早点转行吧,.net 不行了,微软块倒闭了。
对了,世界上最好的语言是 PHP,滑稽.jpg
cjw1115
2018-09-10 17:23:29 +08:00
WebRequst 是什么??难道不是用 HttpClient 吗?
daigouspy
2018-09-10 17:24:47 +08:00
@cjw1115 同意
xiangyuecn
2018-09-10 17:29:52 +08:00
@cjw1115 @daigouspy 用什么都无所谓,关键是需要的功能有没有,有 System.Net.Http.HttpClient 这个框架自带的,配置设置基本没有,因为够简单,满足 98%的需求吧,2%就呵呵,仅此而已
ZhLTE
2018-09-10 17:30:25 +08:00
php 是世界上最好的语言! 什么语言 get 可以发数据流啊
fgodt
2018-09-10 17:33:48 +08:00
阻碍一个人的永远不是语言
xiangyuecn
2018-09-10 17:34:27 +08:00
@ZhLTE 比如 get 一下 www.dropbox.com ,能达到预期( 2 秒超时就是 2 秒超时)的语言就是 ok,.net 就是渣渣
catcn
2018-09-10 17:35:55 +08:00
var a = document.getElementsByName('description')[0].content;
console.info(a.substring(27, 29));
yulitian888
2018-09-10 17:36:10 +08:00
WebClient、HttpClient、HttpWebRequest 的区别不打算了解一下?
ZhLTE
2018-09-10 17:37:19 +08:00
你是想要一个 无论数据是否传输 connect 时间 2s 就算超时的方法吗
xiangyuecn
2018-09-10 17:37:40 +08:00
@catcn 刀呢
enenaaa
2018-09-10 17:38:09 +08:00
能写这么长的文来喷也是真爱
xiangyuecn
2018-09-10 17:42:14 +08:00
@yulitian888 字面意思 HttpClient extend WebClient,WebClient using HttpWebRequest,仅字面意思

@ZhLTE 差不多这意思,从请求创建开始,不管是哪里卡了,只要到时间还么有最终结果就是超时
xupefei
2018-09-10 17:47:32 +08:00
把这个连接扔到 Task 里也不行?
daigouspy
2018-09-10 17:49:56 +08:00
@xiangyuecn 包在一个线程里面,时间到就 abort,绝对好使。你的需求是应用层面了,不应该要求类库自带,类库只是提供基本需求,你的需求需要自己包装。
ZhLTE
2018-09-10 17:54:59 +08:00
可以试试 task 的 CancellationTokenSource
luozic
2018-09-10 17:55:26 +08:00
丰富了 block 名单
crab
2018-09-10 17:56:46 +08:00
winhttp
xiangyuecn
2018-09-10 17:57:34 +08:00
@xupefei 隔壁 java 笑了,哈哈哈,一些简单功能的缺失,用大的代价来弥补一下的做法,不到万不得已,不开相对重量级的 task,毕竟大部分请求 50ms 以内就完成了,一个 task 下来可能额外需要等待 0-50ms 才会做实际的任务

@daigouspy 一样

网络请求这种耗费时间的,按理应该提供比较精细的超时控制,jdk 就没有这个问题。
想到正则表达式都有超时控制,一个网络请求基本的东西,还要开线程控制超时,就是底层太简陋了。
.net 明显的缺陷看 dns 查询部分,太不靠谱
zkd8907
2018-09-10 17:58:03 +08:00
blockList.push(this);

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/487915

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX