为什么HttpWebRequest的GetResponse方法会阻塞这么长时间?

5
我有一些相当简单的代码,可以将照片或视频上传到端点(使用HTTP PUT或POST)。偶尔会出现连接关闭异常,实际上照片/视频已经成功上传,异常是在调用GetResponse时发生的。
我注意到GetResponse处理的时间可能非常长。通常比将照片上传到服务器的实际时间还要长。我的代码使用RequestStream.Write向Web服务器写入数据。
我进行了一个小测试,上传了大约40个大小从1MB到85MB的照片/视频到服务器,GetResponse返回的时间从3秒到40秒不等。
我的问题是,这是正常的吗?这只是我上传这些文件的服务器需要多长时间来处理我的请求并响应的问题吗?查看Fidder HTTP跟踪记录,似乎是这种情况。
FYI,我的上传是HTTP 1.0,超时值设置为无限制(超时和ReadWriteTimeout都是如此)。

1
Omar:如果你在 Fiddler 中右键点击一个会话并选择“属性”,你可以查看该会话的计时器集合。其中两个有趣的值是“ServerGotRequest”和“ServerBeginResponse”。那么它们之间的差值是多少? - EricLaw
2个回答

6
如果服务器在Fiddler中显示确实需要很长时间才能返回任何数据,那就是问题所在。上传一个85MB的附件本来就需要很长时间,然后服务器还要处理它。你无法做太多事情——除非你能够在调用返回之前使用异步方法继续工作。

但是,Fiddler到底显示了什么并不完全清楚——它是否显示了服务器发送响应之前的长时间等待?如果是这样,你没有太多办法。我惊讶于连接被关闭,不过这是另一回事了。如果你看不到你的数据被写入服务器,那就是另外一回事。

你是否正在处理返回的响应?如果没有,你可能会保持活动状态的连接。如果明确是HTTP 1.0,则这不应该是问题,但根据我的经验,这是“挂起”Web调用最常见的原因。

基本上,如果你不处理WebResponse,它通常会(至少在HTTP 1.1和keepalive中)保持连接。单个主机可以打开的连接数有限,因此在下一个响应进行之前,你可能必须等待早期响应完成。

如果这是问题所在,一个简单的using语句就是答案:

using (WebResponse response = request.GetResponse())
{
    ...
}

是的,我正在使用响应中的using方法并读取GetResponseStream。在这种情况下,听起来我只能接受它需要很长时间这个事实... - Omar Shahine

0

是的,响应时间可能比上传时间长得多。在请求发送到服务器后,它必须被处理并返回响应。在请求被处理之前可能会有一些时间,然后文件通常会被保存在某个地方。之后,服务器将创建响应页面并将其发送回来。

IIS每次只处理一个用户的一个请求,因此如果您在第一个上传完成之前开始另一个上传,则它将等待第一个上传完成,然后才开始处理下一个请求。


1
“<<IIS每次只能处理来自每个用户的一个请求>>这是绝对不正确的。我猜你把IIS和ASP的“Session”对象混淆了,它确实持有一个互斥锁,可能会限制每个用户并发执行的页面数量。” - EricLaw
@EricLaw:我不确定网页服务器的哪个部分限制了引擎每个用户只能访问一个页面,但既然这是一个.NET问题,我们谈论的应该是经过ASP.NET引擎处理的请求。可以确定的是,服务器每次只会同时处理来自每个用户的一个请求。 - Guffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接