HttpWebRequest在第二次调用时超时

本文关键字:超时 调用 第二次 HttpWebRequest | 更新日期: 2023-09-27 17:53:31

为什么下面的代码在第二次(和后续)运行时超时?

代码挂起于:

using (Stream objStream = request.GetResponse().GetResponseStream())

,然后导致一个WebException,说请求已经超时。

我已经尝试了WebRequestHttpWebRequest

编辑:似乎代码在request.GetResponse()中摔倒了

编辑:这篇文章建议这可能是一个GC问题-> http://www.vbforums.com/showthread.php?t=610043 -根据这篇文章,如果提琴手在后台打开,问题就会减轻。

服务器已经就绪,可以接受请求。

    private string GetQLMResponse(string URL)
    {
        HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
        request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
        request.KeepAlive = false;
        request.Timeout = 5000;
        request.Proxy = null;
        // Read stream
        string responseString = String.Empty;
        try
        {
            using (var response = request.GetResponse())
            {
                using (Stream objStream = response.GetResponseStream())
                {
                    using (StreamReader objReader = new StreamReader(objStream))
                    {
                        responseString = objReader.ReadToEnd();
                        objReader.Close();
                    }
                    objStream.Flush();
                    objStream.Close();
                }
                response.Close();
            }
        }
        catch (WebException ex)
        {
            throw new LicenseServerUnavailableException();
        }
        finally
        {
            request.Abort();
            request = null;
            GC.Collect();
        }
        return responseString;
    }

抛出webeexception is:

{"操作已超时"}[System.Net。webeexception]:{"操作超时"}数据:{System.Collections.ListDictionaryInternal}HelpLink:零InnerException:零消息:"操作已超时"来源:"系统"StackTrace: " at System.Net.HttpWebRequest.GetResponse()'r'n at IQX.Licensing.License. "GetQLMResponse(String URL) in C:'Users'jd'SVN'jd'Products'Development'JAD.Licensing'JAD.Licensing'License.cs:line 373"TargetSite: {System.Net。WebResponse GetResponse ()}


Update: OK所以下面的代码现在可以工作了。日志含义servicePoint将超时设置为接近4分钟。更改请求对象上的ServicePoint.ConnectionLeaseTimeout意味着请求现在在5000ms后被销毁。感谢所有人的帮助,也感谢这两个页面:

  1. http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
  2. http://msdn.microsoft.com/en-us/library/6hszazfz (v = VS.80) . aspx

    private string GetQLMResponse(string URL)
    {
        HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
        request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
        request.KeepAlive = false;
        request.Timeout = 5000;
        request.Proxy = null;
        request.ServicePoint.ConnectionLeaseTimeout = 5000;
        request.ServicePoint.MaxIdleTime = 5000;
        // Read stream
        string responseString = String.Empty;
        try
        {
            using (WebResponse response = request.GetResponse())
            {
                using (Stream objStream = response.GetResponseStream())
                {
                    using (StreamReader objReader = new StreamReader(objStream))
                    {
                        responseString = objReader.ReadToEnd();
                        objReader.Close();
                    }
                    objStream.Flush();
                    objStream.Close();
                }
                response.Close();
            }
        }
        catch (WebException ex)
        {
            throw new LicenseServerUnavailableException();
        }
        finally
        {
            request.Abort();
        }
        return responseString;
    }
    

HttpWebRequest在第二次调用时超时

在前面的回答之后,我想再补充一些东西。默认情况下,HttpWebRequest只允许2个连接到同一主机(这是HTTP 1.1的"好"),

是的,它可以被覆盖,不,我不会告诉你如何在这个问题,你必须问另一个:)我想你应该看看这篇文章。

我认为你仍然没有完全处置与HttpWebRequest连接的所有资源,所以连接池开始发挥作用,这就是问题所在。我不会尝试对抗每台服务器2个连接的规则,除非你真的需要。

正如上面的一个海报所指出的,Fiddler在这种情况下对你有点伤害。

我会在你的catch之后添加一个很好的finally {}子句,并确保如上所述,所有流都被刷新,关闭,对请求对象的引用被设置为null。

请让我们知道这是否有帮助。

必须妥善处理由request.GetReponse()获得的WebResponse。试试这个(删除request.Abort()GC.Collect()调用):

using (var wresponse = request.GetResponse())
{
   using (Stream objStream = wresponse.GetResponseStream())
   {
        // ...
   }
}

编辑:由于它仍然不起作用,我建议您使用空窗口应用程序进行测试。这样,你可以隔离app.config问题或每台主机最大并发调用*(你是否在应用程序的其他地方使用其他webrequest对象到该主机;).

希望这能解决你的问题,我已经没有主意了!

  • 请看Jon Skeet的回答。

正如您所说,在后台运行fiddler可以缓解这个问题。这是因为小提琴力关闭了任何响应。在Sam B的上述帖子上延伸,我将确保响应像这样关闭:

using (var wresponse = request.GetResponse())
{
   using (Stream objStream = wresponse.GetResponseStream())
   {
        // ...
   } 
   wresponse.close();
}

也可以将代理设置为null,如下所示:

 request.Proxy = Null;

因为。net框架会出去搜索代理,除非你显式地这样做。当fiddler运行时,这种影响将被缓解,因为fiddler的代理将被直接找到。

在对服务器的后续请求中遇到同样的超时问题,尽管正确地处理/刷新/关闭所有内容。尝试刷新您的连接组,为我工作:

myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);

同时,确保你没有无意中在应用程序的其他地方创建其他HttpWebRequest/Request对象,这些对象没有被正确终止/处置,因为这将增加服务点中的连接数量。

我有同样的问题,我解决了这个问题,确保在每个创建的请求对象上调用 Abort() 方法。

您是否使用默认名称为WindowsFormsAppN的测试应用程序?我遇到了同样的问题,我花了一周的时间来调试,因为它在我的生产代码中有效,但在我正在构建的简单测试解决方案中无效。最后,我确定这种行为是使用默认解决方案名称而不是正确命名的解决方案所特有的。

编辑:我发现我的问题与使用BitDefender作为我的防病毒软件有关。WindowsFormsAppN程序全部被阻塞。

我读了上面标记为答案的帖子,上面它并没有真正为我工作。我最终使用using标签重写了代码,并添加了其他人推荐的CloseConnectionGroup段。最终代码是这样的:

System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(imageUrl);
                webRequest.AllowWriteStreamBuffering = true;
                webRequest.Timeout = 30000;
                webRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
                webRequest.ServicePoint.MaxIdleTime = 5000;
                using (System.Net.WebResponse webResponse = webRequest.GetResponse())
                {
                    using (System.IO.Stream stream = webResponse.GetResponseStream())
                    {
                        image = System.Drawing.Image.FromStream(stream);
                    }
                }
                webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
                webRequest = null; 
            }

当我添加这个

myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);

在vb.net中寻找第二次超时的人:确保您一直在使用:

  1. response.close ()

  2. response.dispose ()

之后的

每次

你使用你的webresponse。

我将http超时时间设置为10分钟,它对我有效。

设置为timeout=infinite需要更多的时间,我的程序进入挂起模式