首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Net.WebException:操作已超时

System.Net.WebException:操作已超时
EN

Stack Overflow用户
提问于 2009-08-01 00:44:09
回答 6查看 153K关注 0票数 28

我有一个很大的问题:我需要一次发送200个对象并避免超时。

代码语言:javascript
复制
while (true)
{

    NameValueCollection data = new NameValueCollection();
    data.Add("mode", nat);

    using (var client = new WebClient())
    {
        byte[] response = client.UploadValues(serverA, data);
        responseData = Encoding.ASCII.GetString(response);

        string[] split = Javab.Split(new[] { '!' },  StringSplitOptions.RemoveEmptyEntries);
        string command = split[0];
        string server = split[1];
        string requestCountStr = split[2];

        switch (command)
        {
            case "check":
                int requestCount = Convert.ToInt32(requestCountStr);

                for (int i = 0; i < requestCount; i++)
                {
                    Uri myUri = new Uri(server);
                    WebRequest request = WebRequest.Create(myUri);
                    request.Timeout = 200000;
                    WebResponse myWebResponse = request.GetResponse();
                }
                break;
        }
    }    
}

这会产生以下错误:

代码语言:javascript
复制
Unhandled Exception: System.Net.WebException: The operation has timed out  
at System.Net.HttpWebRequest.GetResponse()  
at vir_fu.Program.Main(String[] args)

requestCount循环在我的基代码之外工作得很好,但是当我将它添加到我的项目中时,我得到了这个错误。我试过设置request.Timeout = 200;,但是没有用。

EN

回答 6

Stack Overflow用户

发布于 2009-08-01 00:55:55

这是它所说的意思。操作花费的时间太长,无法完成。

顺便说一句,看看WebRequest.Timeout,你会看到你已经设置了1/5秒的超时。

票数 36
EN

Stack Overflow用户

发布于 2009-08-01 06:12:57

关闭/释放WebResponse对象。

票数 34
EN

Stack Overflow用户

发布于 2009-08-01 01:05:22

我不确定你在哪里使用WebClient.UploadValues的第一个代码样本,这还不够继续,你能粘贴更多你周围的代码吗?关于您的WebRequest代码,这里有两件事在起作用:

  1. 您只请求响应的头部**,您永远不会通过打开并读取(直到其末尾) ResponseStream来读取响应的正文。正因为如此,WebRequest客户机很有帮助地让连接保持打开状态,期望您随时请求正文。在您读取响应体完成(这将自动关闭流)、清理并关闭流(或WebRequest实例)或等待GC执行操作之前,您的连接将保持打开。
  2. 到同一主机的默认最大活动连接数为2。这意味着您用完了前两个连接,然后再也不会处理它们,因此您的客户端没有机会在超时之前完成下一个请求(这是毫秒,顺便说一下,因此,您已将其设置为0.2秒-默认值应该很好)。

如果你不想要响应的正文(或者你刚刚上传或POSTed了一些东西,并不期望得到响应),只需关闭流,或者关闭客户端,这将为你关闭流。

解决此问题的最简单方法是确保在可处理对象上使用using blocks:

代码语言:javascript
复制
for (int i = 0; i < ops1; i++)
{
    Uri myUri = new Uri(site);
    WebRequest myWebRequest = WebRequest.Create(myUri);
    //myWebRequest.Timeout = 200;
    using (WebResponse myWebResponse = myWebRequest.GetResponse())
    {
        // Do what you want with myWebResponse.Headers.
    } // Your response will be disposed of here
}

另一种解决方案是允许到同一主机的200个并发连接。但是,除非您计划对此操作进行多线程处理,因此需要多个并发连接,否则这对您没有真正的帮助:

代码语言:javascript
复制
 ServicePointManager.DefaultConnectionLimit = 200;

当您在代码中获得超时时,最好的做法是尝试在您的代码之外重新创建该超时。如果不能,那么问题可能出在您的代码上。为此,我通常使用cURL,如果是一个简单的GET请求,则只使用web浏览器。

**实际上,您实际上是从响应中请求第一块数据,其中包含HTTP头和正文的开头。这就是为什么在从输出流读取之前可以读取HTTP头信息(如Content-Encoding、Set-Cookie等)的原因。当您读取流时,将从服务器检索进一步的数据。WebRequest与服务器的连接一直保持打开,直到您到达该流的末尾(有效地关闭它,因为它是不可找到的),手动关闭它,否则它会被处理掉。There's more about this here

票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1215488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档