c# - HttpWebRequest 在第二次调用时超时

标签 c# http garbage-collection httpwebrequest webrequest

为什么以下代码在第二次(及后续)运行时超时?

代码卡在:

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

然后引发一个 WebException,表示请求已超时。

我已经尝试使用 WebRequestHttpWebRequest

编辑:似乎代码在 request.GetResponse()

中失败了

编辑:这篇文章表明它可能是一个 GC 问题 --> http://www.vbforums.com/showthread.php?t=610043 - 根据这篇文章,如果 Fiddler 在后台打开,问题就会得到缓解。

服务器在那里并可用于请求。

    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;
    }

抛出的 WebException 是:

{"The operation has timed out"} [System.Net.WebException]: {"The operation has timed out"} Data: {System.Collections.ListDictionaryInternal} HelpLink: null InnerException: null Message: "The operation has timed out" Source: "System" 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()}


更新:好的所以下面的代码现在可以工作了。 servicePoint 将超时设置为接近 4 分钟。更改请求对象上的 ServicePoint.ConnectionLeaseTimeout 意味着请求现在会在 5000 毫秒后销毁。感谢大家的帮助以及这两个页面:

  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 只允许 2 个连接到同一主机(这是 HTTP 1.1 的“优点”),

是的,它可以被覆盖,不,我不会告诉你如何在这个问题中,你必须问另一个问题:) 我认为你应该看看 this post .

我认为您仍然没有完全处理与 HttpWebRequest 连接的所有资源,因此连接池开始发挥作用,这就是问题所在。我不会尝试反对每个服务器 2 个连接的规则,除非你真的必须这么做。

正如上面的一位发帖者所指出的,在这种情况下,Fiddler 对您造成了一些伤害。

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

如果这有帮助,请告诉我们。

关于c# - HttpWebRequest 在第二次调用时超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5827030/

相关文章:

java - 如何使用 Java 套接字 HTTP/1.1 请求下载图像?

google-chrome - 在网络选项卡中输入 "ping"

garbage-collection - 尽管有足够的 PermSize 和 OldGen 空间,JVM 是否仍会遇到 “java.lang.OutOfMemoryError:"

.net - 如何减少花费在 GC 上的时间

c# - 使用c#检查mysql数据库中是否有记录

c# - 基于平台或字节序的条件编译器指令?

c# - 如何在函数代码之前先调用默认构造函数?

c# - 加载 PDF 文档时出错 - iTextSharp PDF

javascript - HTTP 重试更改 url 的参数

c# - 在 .NET 中,清理嵌套字典父级是否会在垃圾回收时释放所有内存?