System.Net.WebException:操作已超时

Posted

技术标签:

【中文标题】System.Net.WebException:操作已超时【英文标题】:System.Net.WebException: The operation has timed out 【发布时间】:2009-08-01 00:44:08 【问题描述】:

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

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;
        
        

这会产生错误:

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;,但没有帮助。

【问题讨论】:

顺便说一句,当您发布代码时,请尝试发布真实代码。您的代码无法编译:WebRequest 构造函数是protected。如果您使用“// ...”代替“...”也会很方便。 【参考方案1】:

它的意思是它所说的。操作完成时间过长。

顺便说一句,看看WebRequest.Timeout,您会发现您已将超时设置为 1/5 秒

【讨论】:

一个有价值的指南.. 谢谢!!【参考方案2】:

关闭/释放您的 WebResponse 对象。

【讨论】:

关闭/处理没有帮助【参考方案3】:

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

    您只是请求响应的标头**,您永远不会通过打开和读取(到其末尾)ResponseStream 来读取响应的正文。因此,WebRequest 客户端有助于保持连接打开,期待您随时请求正文。在您读取响应正文完成(它将自动为您关闭流)、清理并关闭流(或 WebRequest 实例)或等待 GC 完成它的操作之前,您的连接将保持打开状态。

    您与同一主机的默认最大 活动 连接数量为 2。这意味着您用完前两个连接,然后永远不会丢弃它们,这样您的客户端就不会有机会在超时之前完成下一个请求(这是毫秒,顺便说一句,所以您已将其设置为 0.2 秒 - 默认值应该没问题)。

如果您不想要响应的正文(或者您刚刚上传或发布了某些内容并且不希望得到响应),只需关闭流或客户端,它会为您关闭流。

解决此问题的最简单方法是确保在一次性对象上使用使用块:

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 个并发连接到同一主机。但是,除非您计划对此操作进行多线程处理,否则您需要多个并发连接,否则这对您没有帮助:

 ServicePointManager.DefaultConnectionLimit = 200;

当您在代码中遇到超时时,最好的办法是尝试在您的代码之外重新创建该超时。如果不能,问题可能出在您的代码上。我通常为此使用cURL,或者如果它是一个简单的 GET 请求,则只使用一个网络浏览器。

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

【讨论】:

@Matthew:你确定要发送HEAD吗?我想我从未见过这种情况。 对不起,我不是指 HEAD(HEAD 是您请求 only 标头的地方),我的意思是初始响应仅包含标头(这是您通常的如果您刚刚发送了 HEAD 请求,请获取)。我已经编辑以纠正我的错误。 @Matthew:又是什么让你认为响应只包含标题?您是否建议在调用 GetRequestStream 时客户端和服务器之间存在另一个数据包交换? 嗨,马修 B,谢谢您的回复,好的,我的代码这样做: 1 - 开始时(真)//正确工作 1 - 将数据发布到 serverA//正确工作 2 - 接收代码//正确工作 3 - 使用开关(代码)//正确工作 4 - 向 serverB 发送 GET 请求 // 问题在这里 5 - 睡眠 2 分钟 6 - while() 结束; 也许应该改为 // Do what you want with myWebResponse.Headers 而不是 // Do what you want with the HEAD。这可能不会让读者感到困惑。【参考方案4】:

代理问题可能会导致此问题。 IIS webconfig 把这个放在

<defaultProxy useDefaultCredentials="true" enabled="true">
          <proxy usesystemdefault="True" />
        </defaultProxy>

【讨论】:

【参考方案5】:

我记得我在使用 WCF 时遇到了同样的问题,因为我传递的数据量很大。我记得我到处都更改了超时,但问题仍然存在。我最终所做的是将连接作为流请求打开,我需要更改客户端和服务器端,但它是这样工作的。由于是流连接,服务器一直读取直到流结束。

【讨论】:

【参考方案6】:

我遇到了和添加一样的错误

Task.Delay(2000);

在每个请求中都解决了问题

【讨论】:

虽然这种类型的解决方案实际上可能有效,但我不推荐它。这会通过强制每次迭代花费 2 秒人为地减慢该过程。有 200 个项目要处理,这意味着需要 6 分钟以上才能完成,并且并不能真正解决超时的根本问题。我将专注于控制上面建议的流,仅在必要时保持连接打开。这应该允许您的代码以更高的性能水平执行。

以上是关于System.Net.WebException:操作已超时的主要内容,如果未能解决你的问题,请参考以下文章

System.Net.WebException:无法解析远程名称:

System.Net.WebException:操作已超时

System.Net.WebException HTTP 状态码

System.Net.WebException:请求被中止:请求被取消

ArangoDB-NET 错误:System.Net.WebException:'不知道这样的主机 不知道这样的主机'

System.Net.WebException 的 Powershell 处理