【问题标题】:Request timed out frequently请求经常超时
【发布时间】:2012-07-02 16:31:27
【问题描述】:

我一次又一次遇到以下问题,我不知道如何解决它..

我经常遇到以下错误,我不得不restart the IIS 或republish 临时解决问题:

Error Message:Request timed out.
Error Message:ERROR [08S01] [Informix .NET provider]Communication link failure.
Error Message:Thread was being aborted.

我试着做:

<httpRuntime executionTimeout="600" />

但还是同样的问题!!


Stack Trace:
   at System.Web.HttpContext.InvokeCancellableCallback(WaitCallback callback, Object state)
   at System.Web.UI.Page.AsyncPageBeginProcessRequest(HttpContext context, AsyncCallback callback, Object extraData)
   at ASP.appmaster_aspx.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object data)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

我的页面加载:

 protected void Page_Load(object sender, EventArgs e)
        {


            if (Session["emp_num"] != null && !string.IsNullOrEmpty(Session["emp_num"].ToString()))
            {
                try
                {

                    string user_setting = Personalization_DAL.CheckWidgetSettings(int.Parse(Session["emp_num"].ToString()));

                    if (!string.IsNullOrEmpty(user_setting))
                    {
                        user_flag = int.Parse(user_setting);
                    }

                    GetLinkedApp = DB_Connection_s.DB_Connection.GetLinkedAppUser(int.Parse(Session["emp_num"].ToString()));
                    if (!Page.IsPostBack)
                    {
                        //Profile
                        GetProfile();

                        if (Session["emp_app"] != null && !string.IsNullOrEmpty(Session["emp_app"].ToString()))
                        {
                            BindAvailableSystems(Session["emp_app"].ToString());
                        }

                        BindMainSystems();

                        if (GetLinkedApp > 0)
                        {
                            rlv_available_sys.Visible = true;
                            h5_app.Visible = true;
                            lbtn_addApp.Visible = false;
                            h4_app.Visible = false;
                            intro.Visible = true;

                        }
                        else
                        {
                            rlv_available_sys.Visible = false;
                            h5_app.Visible = false;
                            lbtn_addApp.Visible = true;
                            h4_app.Visible = true;
                            intro.Visible = false;
                        }
                        //Applications
                        if (rlv_available_sys.Visible == true)
                        {
                            Session["emp_app"] = GetLinkedApp;
                            BindAvailableSystems(Session["emp_app"].ToString());
                            if (user_flag > 0)
                            {
                                Get_UserApplicationSystems(1, 1, GetLinkedApp.ToString());
                            }
                            else
                            {
                                Get_UserApplicationSystems(user_flag, 1, GetLinkedApp.ToString());
                            }

                        }
                        //services
                        Get_MainSystems(user_flag);
                        if (GetLinkedApp > 0)
                        {
                            GetServiceInformation();
                        }
                        string[] statistics = TrackUser();
                        base.TraceActivity("Enter the portal", "https://" + Request.Url.Authority + "/AppMaster.aspx", statistics[0], statistics[1], statistics[2]);
                    }

                    TraceSystemsMode();
                }
                catch (Exception ee)
                {
                    string message = ee.Message;
                }

            }
            else
            {
                Response.Redirect("LoginPage.aspx", false);
            }
        }

我的通用处理程序:

public void ProcessRequest(HttpContext context)
        {
            try
            {
                using(Stream photo_stream = Photo_DAL.RetrievePhoto(int.Parse(context.Session["emp_num"].ToString())))
               {
                byte[] photo_bytes = Photo_DAL.StreamToByteArray(photo_stream);
                if (photo_bytes == null)
                {
                    photo_bytes = File.ReadAllBytes(Path.Combine(context.Server.MapPath("~/images/PortalImages/"), "user.png"));
                }
                //context.Response.ContentType = "image/png";
                context.Response.BinaryWrite(photo_bytes);
                }
            }
            catch (Exception ee)
            {
            }

        }

【问题讨论】:

  • 请告诉你对请求做了什么操作
  • 只需连接到 DB 以带来数据并插入数据并通过通用处理程序获取图像..
  • 好的,现在将您的代码分成 3 个部分 1) 获取数据 2) 插入数据和 3) 图像处理程序,并通过一次禁用一个来运行以找出其中哪些需要时间。
  • 如果我知道某个特定部分确实比其他部分花费了很长时间,我该怎么办?假设图像处理程序..
  • 如果你确定它是图像处理程序,那么你应该增加你的执行超时并再试一次,如果它仍然不起作用,那么重新处理你的图像处理逻辑就没有其他出路了。这是您的帮助链接codebetter.com/petervanooijen/2006/06/15/…

标签: asp.net performance .net-3.5 iis-7.5 informix


【解决方案1】:

这是推测,因为有很多引用的代码我们没有从问题中发布的 sn-p 中看到。

我假设您没有正确处理数据库连接 (DB_Connection_s) 有几个原因。

A) 通过重置修复

    I get the following errors frequently , and i had to restart the IIS or 
    republish to fix the problem temporary`

对我来说,这表明您正在使用到数据库的所有连接,因为当您重新启动或重新发布时,所有当前连接都将被删除。

B) 没有明确的处置

在您的代码中,您引用了DB_Connection_s,但是它没有包含在 using 块中,也没有实例化,这意味着它很可能是一个静态类或方法(如果没有该引用的代码很难判断)。

建议

确保始终正确处理数据库连接。他们需要在完成后调用 .Dispose()。这通常是通过获取包含上下文的类并让它实现IDisposable 然后用 using 语句包装您对该类的调用来完成的。 using 语句将自动调用Dispose 方法。如果您不想实现IDisposable,您也可以在查询完成后直接在连接上调用.Dispose(),明确(不建议)处理数据库连接。

编辑以响应新添加的 cmets:

@just_name - 从 cmets 中的代码来看,在我看来可能存在问题。依靠~DBConnection() 来处理你的连接,只调用.Close(),而不是关闭一个流,这对我来说很突出。

i) 终结器可能需要很长时间

使用终结器来处理连接可能会有风险,因为您永远无法确定它何时被调用。 “垃圾回收期间终结器执行的确切时间未定义。” -MSDN Object.Finalize。如果系统在处理任何连接之前有大量资源,这可能会导致系统等待很长时间,从而减慢请求。

ii) Close 不是 Dispose

虽然在连接上调用.Close() 在技术上是安全的,但它可能会导致生产问题。原因是连接将关闭,但事件处理程序将保留,有时如果涉及延迟加载或动态代理,这些事件处理程序可以保存连接的副本。

iii) 使用处置

a) 明确处理您的连接

始终显式处理您的连接,不要等待垃圾收集器执行此操作。处理它的最佳实践方法是在访问 DBConnection 类时使用 using(){} 块。为此,您可以进行一些更改:

定义 DBConnection 以实现 IDisposable 以便它可以在 using 块中使用

public class DBConnection : IDisposable
{
  //other methods already in here
  public void Dispose()
  {
   //Close_Connection(); Call this if you want, but you MUST call 
   //.Dispose on your connections
   connection.Dispose();
  }
}

这将允许您像这样创建一个新的 DBConnection:

using( var DB_Connection_s = new DBConnection() )
{
 //todo: interact with database connection
}

当到达最终的} 时,using 块将自动调用.Dispose(),并保证释放连接。此外,这允许更短的数据库事务时间发生,如果数据库访问涉及任何排队,则可以提高查询和请求速度。

如果你不喜欢 using 块的实现,那么至少在你使用 close 的地方将.Close() 更改为.Dispose(),并确保没有可能导致.Dispose() 不存在的执行路径在数据库访问完成后立即调用。

b) 在非托管资源上使用 .Dispose()

始终对非托管资源使用.Dispose()。有几种方法可以做到这一点,但最佳实践方法是使用 using(){} 块。我注意到您可以在一个地方专门使用必须处理的代码中的流来实现这一点。

这是有问题的代码之一:

IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader(); 
if (ifxDataReaders.Read()) { 
 item = (int)ifxDataReaders["emp_num"]; 
} 
ifxDataReaders.Close();

我对此有几个问题。首先,您正在调用上面讨论过的.Close()。其次,因为这是在 try 块中,所以 ifxDataReaders 可能会抛出异常并且程序将继续运行而无需关闭或处置阅读器。这会导致很多问题。

您应该确保在您的非托管资源上始终调用.Dispose。您可以使用 using 块(隐式始终调用 .Dispose())来执行此操作。

using(IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader())
{
 if (ifxDataReaders.Read()) { 
  item = (int)ifxDataReaders["emp_num"]; 
 } 
}

【讨论】:

  • DB_Connection_s 它不是用于处理数据库操作的类,尽管名称有时会令人困惑。所有连接都在finally 语句中或在我的数据库中的操作结束时关闭层。这还不够吗?!
  • 我添加了与用户图像相关的代码(通用处理程序)。
  • 我如何处理连接的示例:
  • @just_name - 您应该对存在的非托管资源使用 dispose。至于以前的使用,我不知道为什么没有问题,或者可能因为系统资源不同而很少发生。如果问题不是数据库连接,那么在浏览器中查看每个页面加载发送多少流量可能是相关的。理想情况下,它应该小于 1 MB,即 2 秒的加载时间。
  • @just_name - 在 firefox 或 google 中,在转到您要测量的页面之前,打开 firebug 或检查控制台。在控制台中导航到网络或网络选项卡。然后,转到您要测量的页面并查看网络标签中的总流量。
【解决方案2】:

因此,我对 Zia 的评论表示赞成,建议您单独运行这些部件以隔离超时。 Informix 连接是否有可能出错?

数据库查询有两个超时,连接超时和命令超时。这些都不会使用 executionTimeout 值。我没有尝试使用 Informix 提供程序,但是如果服务器繁忙或命令对象等待长 SQL 查询运行,我会增加连接对象的超时时间。

这是在 Informix 连接对象上设置 connectionTimeout 的链接... http://publib.boulder.ibm.com/infocenter/idshelp/v115/index.jsp?topic=%2Fcom.ibm.net_cc.doc%2Fcom.ibm.swg.im.dbclient.adonet.ref.doc%2Fdoc%2FDB2ConnectionClassConnectionTimeoutProperty.htm

【讨论】:

  • 我在连接字符串中设置了Connection Lifetime=30; 并增加了该时间但徒劳无功
【解决方案3】:

主要问题是,为什么要花这么长时间?为什么某些页面的点击时间会超过 30 秒?这么慢的网站真的可以上线吗?

我们必须看看如何降低性能以使请求在 30 秒内完成。

你能分享一下代码吗?让我们看看代码的瓶颈在哪里。

【讨论】:

    【解决方案4】:

    我知道它不属于Error Message:Request timed out,但它可能与Error Message:Thread was being aborted. 有链接。因此,由于我们没有任何代码示例,我认为当它是在 Try-Catch 块内制作时,可以认为它可能是一个Response.Redirect("aPage.aspx") 问题。

    如果是您的情况,请尝试在 Response.Redirect 方法的 EndResponse 参数中添加“False”,如下所示:

    try {
        // [... SOME CODE ...]
        Response.Redirect("aPage.aspx", False)
    } catch (Exception e) {
        // [... YOUR CATCH ...]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 2016-05-27
      相关资源
      最近更新 更多