System.Net.WebRequest - 超时错误

5
下面的代码段出现了错误: 错误信息:"操作已超时" 错误源:at System.Net.httpWebRequest.GetResponse() 这个方法是调用一个URL并获取响应对象。
注意:在我的环境中一切正常,但当我将相同的代码发送到生产环境时,它会显示超时错误。
public GetUpdatedInventoryUnitValues(Vehicle aeVehicle)
{
            WebRequest oWebRequest = null;
            StringBuilder oStringBuilder = null;
            StreamReader oStreamReader = null;
            dcDealerDetails = new Dictionary<string, string>();

            MSRP = string.Empty;
            NetPrice = string.Empty;
            string strLine = string.Empty;
            string strURL = GetUpdatedInventoryUnitValues.GetFormattedURL(aeVehicle);

            try
            {
                /* Open the requested URL */
                oWebRequest = WebRequest.Create(strURL);
                oWebRequest.Method = "GET";
                oWebRequest.ContentType = "application/xml";
                /* Get the stream from the returned web response */
                oStreamReader = new StreamReader(oWebRequest.GetResponse().GetResponseStream());
                /* Get the stream from the returned web response */
                oStringBuilder = new StringBuilder();
                /* Read the stream a line at a time and place each one into the stringbuilder  */
                while ((strLine = oStreamReader.ReadLine()) != null)
                {
                    /* Ignore blank lines */
                    if (strLine.Length > 0)
                        oStringBuilder.Append(strLine);
                }

                string[] tempArray = null;
                string[] tempNextArray = null;
                //Split string by semicolon as a separater
                tempArray = Data.SplitString(oStringBuilder.ToString(), new char[] { ';' });

                if (tempArray != null)
                {
                    foreach (string invUnits in tempArray)
                    {
                        //Split string by '=' as a separater
                        tempNextArray = Data.SplitString(invUnits, new char[] { '=' });

                        if (tempNextArray != null && tempNextArray.Length == 2)
                        {
                            switch (tempNextArray[0].ToLower())
                            {
                                //case "msrp":
                                //    MSRP = Data.RemoveDoubleCode(tempNextArray[1]);
                                //    break;
                                case "netprice":
                                    NetPrice = Data.RemoveDoubleCode(tempNextArray[1]);
                                    break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorLog.ErrorMessage = ErrorLog.Separator;
                ErrorLog.ErrorMessage = "Exception during posting data to another application .";
                ErrorLog.ErrorMessage = "ERROR MESSAGE : " + ex.Message;
                ErrorLog.ErrorMessage = "ERROR SOURCE: " + ex.StackTrace.ToString();

            }
            finally
            {
                if (oStreamReader != null)
                {
                    oStreamReader.Close();
                }
                if (oWebRequest != null)
                {
                    oWebRequest = null;
                }
            }
        }

请问我做错了什么或者有什么遗漏吗?

你确定你的请求没有问题,不会超时退出代码吗?我的意思是,你是否尝试在浏览器中直接启动它? - user1409909
一切在我的端口正常运行,但当我将同样的代码发送到生产环境时,就会显示超时错误。 - A Developer
你们的开发平台和生产平台有什么区别?是否存在防火墙或类似的东西可能会阻止你的请求? - user1409909
不确定防火墙是否阻止了生产站点...如果是这种情况,似乎是一个潜在的原因.. - A Developer
3个回答

17

你是否发现最开始的几个请求可以正常响应,然后就开始出现超时问题了?如果是这样,我怀疑问题出在这里:

oStreamReader = new StreamReader(oWebRequest.GetResponse().GetResponseStream());

你正在获取响应,但从未处理它。你应该使用:

using (var response = oWebRequest.GetResponse())
{
    ...
}

实际上,如果你在整个代码中使用using语句,你可以完全摆脱finally块。

另外,这是一个相当长的方法 - 77行! - 更糟糕的是,它看起来实际上是一个构造函数:

  • 尝试将其拆分为更小、更易理解、更易测试的块
  • 尽量避免在构造函数中执行大量操作

这在我的循环中使用250个调用运行良好,但在生产中几乎所有都超时了。在代码部分,是的,我应该这样做。 - A Developer
@RatanSharma:你从生产环境中获取的URL是什么?有可能只是超时了吗? - Jon Skeet
上述函数来自工具..该工具正在生产站点中运行...该函数调用一个URL,该URL会返回一些响应..当我在我的系统中运行该工具时,它可以正常工作,但是在生产服务器上运行相同的工具时,它会超时。 - A Developer
@RatanSharma:你从系统中获取了响应- 但如果你从生产系统(如浏览器)中获取它,会发生什么? - Jon Skeet
经过一年多的时间,你再次在不知情的情况下帮助了我,非常感谢@JonSkeet。我刚刚添加了你建议的using语句,现在它像魔法一样运行良好。 - user1162766
显示剩余3条评论

2

分享一下我的经验。

我也遇到了“操作超时”的错误。

我尝试使用WebClient和WebRequest(设置超时时间),但仍然出现错误。

原因是我没有释放响应。

所以我按照上面提到的方法进行了处理:

using (var response = oWebRequest.GetResponse())

{
    ...
}

它解决了这个问题...


1

我个人在我的一个程序中使用这段代码,它完美地运行:

    WebRequest webRequest = WebRequest.Create(requestUri);
    webRequest.Credentials = new NetworkCredential(login, password);
    WebResponse webResponse = webRequest.GetResponse();
    Stream response = webResponse.GetResponseStream();
    StreamReader reader = new StreamReader(response);

所以我认为这不是来自你的代码,而是来自你的生产平台。


4
如果你没有处理回应,那么它并不是完美运作——你只是侥幸而已。 - Jon Skeet
使用您发布的代码后,使用结束时会处理响应吗? - user1409909
1
是的。你应该对几乎所有实现了 IDisposable 接口的对象使用 using 语句,以确保清理工作得到执行。 - Jon Skeet

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