【问题标题】:Time out period not elapsed, but still timing out (see code)?超时时间没有过去,但仍然超时(见代码)?
【发布时间】:2010-10-25 07:40:11
【问题描述】:

好的,大约 3-4 分钟后,我一直收到此错误:

 Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

Source Error:

Line 93: 
Line 94:             DataSet getData;
Line 95:             getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPara);
Line 96: 
Line 97:             foreach (DataRow dr in getData.Tables[0].Rows)

这是代码,我认为我没有正确执行某些操作,但我将超时设置为 5000 秒,所以它必须是其他内容。您会注意到它完全是过程调用的嵌套循环。我得到每家公司,然后得到分配给每家公司的每门课程,然后对于每门课程,我得到所有用户活动的报告。大约有 250 家公司,每家公司有 2-70 门课程,每家公司每门课程报告有 8 到 1000 名用户……所以我们在这里处理大量数据。对 get 报告的最后调用也是一个相当庞大的存储过程......

我正在尝试将数据转换为一种新形式,以便以后使用起来更快、更容易,但现在我必须解析我们拥有的内容并以新的方式发布。这一切都在同一个数据库中,但我不确定如何仅在 SQL 中完成这一切。基本上我正在使用我们的报告工具使用的存储过程来获取要发布到新表的数据。但是我需要为每家公司的每门课程运行该程序,然后发布每家公司每门课程的报告中返回的每个用户的数据......这是巨大的......

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
using Mexico.Data;

public partial class admin_tools_Optimus : System.Web.UI.Page
{
    protected int step = 0;
    protected string[] companies = new string[260];
    protected string[] coursestrings = new string[260];
    protected int total = 0;
    protected int[] totalcourses = new int[260];

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Proceed(object sender, EventArgs e)
    {
        DataSet getCompanies = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Companies_All_Get");

        int counter = 0;

        foreach (DataRow dr in getCompanies.Tables[0].Rows)
        {
            lstData.Items.Add(dr["companyid"].ToString() + ": " + dr["companyname"].ToString());
            companies[counter] = dr["companyid"].ToString();
            counter++;
        }
        lblCurrentData.Text = counter.ToString() + " companies ready, click next to get all company courses.";
        total = counter;

        GetCompanies();
    }


    protected void GetCompanies()
    {
        string[,] courses = new string[260, 200];

        for (int i = 0; i < total-1; i++)
        {
            DataSet getBundles = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "CompanyCourses_ByCompanyID_Get_Sav", new SqlParameter("@companyid", companies[i]));

            int counter = 0;

            foreach (DataRow dr in getBundles.Tables[0].Rows)
            {
                courses[i, counter] = dr["bundleid"].ToString();
                counter++;
            }

            string allID = "";

            allID += courses[i, 0];

            for (int ii = 0; ii < counter; ii++)
            {
                allID += "," + courses[i, ii];
            }
            Response.Write(allID + " <br/>");
            coursestrings[i] = allID;
            totalcourses[i] = counter;
        }
        GetUsers();
    }

    protected void GetUsers()
    {
        for (int i = 0; i < total - 1; i++)
        {
            SqlParameter[] objPara = new SqlParameter[10];
            objPara[0] = new SqlParameter("@CompanyID", companies[i]);
            objPara[1] = new SqlParameter("@CourseID", coursestrings[i]);
            objPara[2] = new SqlParameter("@DateRangeType", 1);
            //objPara[3] = new SqlParameter("@StartDate", startDate);
            //objPara[4] = new SqlParameter("@EndDate", System.DateTime.Now.ToString("MM/dd/yyyy"));
            objPara[5] = new SqlParameter("@UserName", "");
            objPara[6] = new SqlParameter("@StartIndex", 1);
            objPara[7] = new SqlParameter("@MaximumRows", 100000);



            DataSet getData;
            getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["connstr"].ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPara);

            foreach (DataRow dr in getData.Tables[0].Rows)
            {
                Response.Write("user: " + dr["userid"].ToString() + " / course: " + dr["bundleid"].ToString() + " - progress: " + dr["viewed"].ToString() + " - scored: " + dr["scored"].ToString() + "<br/><br/>");
            }
        }
    }
}

页码:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Optimus.aspx.cs" Inherits="admin_tools_Optimus" Debug="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="lblCurrentData" runat="server" Text="Click next to get all Companies"/><br />
        <asp:Button ID="btnNext" runat="server" Text="Next" OnClick="Proceed" />
        <br/>
        <asp:ListBox ID="lstData" runat="server" height="300" Width="300" />
    </div>
    </form>
</body>
</html>

【问题讨论】:

  • 我不能确切地知道你想要达到的最终结果是什么,但看起来你应该能够在数据库的一次往返中做到这一点,而不是你目前的方式有它。我认为这应该可以为您节省大量时间。
  • 是的,我也在想同样的事情,但如果我能让它像这样工作,那么工作量就会少得多,因为这只是一次数据转换。

标签: asp.net sql timeout


【解决方案1】:

从 asp.net 页面与数据库通信时,您必须了解五种不同的超时:

  1. 数据库连接超时在您的SQLConnection 对象上设置,可能通过连接字符串。
  2. 数据库命令超时在您的 SQLCommand 对象上设置。
  3. ASP.Net 脚本超时通过Server.ScriptTimeout 在您的页面上设置。
  4. 其他 IIS 超时 由 IIS 强加在您的页面上。见此链接:http://msdn.microsoft.com/en-us/library/ms525386.aspx?ppud=4
  5. 互联网浏览器超时 浏览器/客户端只会等待这么长时间。您无法控制它,因此无需担心它,但您仍然应该知道它存在。

请务必检查我列出的前 4 个。

通常我也会说 3 分钟以上的时间来等待页面加载方式。您可能有足够的数据来证明查询时间的合理性,但如果是这样的话,对于用户来说,数据太多,无法在一页中进行真正的评估。考虑拆散它。但在这种情况下,听起来您正在构建一个需要不经常运行的“报告”。虽然我仍然质疑此类报告的优点(手动处理的数据太多 - 将其转储到事实表或类似的地方以进行额外的数据挖掘),但我知道企业通常无论如何都需要它们。

另外,通过查看您的代码,我可以看到您可以在哪里编写所有这些作为一个大查询而不是一堆小查询。这对数据库来说会更有效率,但代价是组装结果的一些额外复杂性,但结果会运行得更快。但是对于不经常运行的东西,当你已经构建了这样的存储过程时,你可能无法证明重写东西是合理的。

所以我会给你一个长期运行页面的通行证......这次。

【讨论】:

  • 非常感谢,好详尽的帖子,帮助我更好地理解事情!我是n00b。 +1
【解决方案2】:

这是一个极其糟糕的代码重用示例。与其重复使用使您循环遍历所需的所有输入变量的存储过程,不如编写一个新的基于集合的过程,该过程根据连接选择信息。它会快得多(当然假设您已经正确索引)。在访问数据库时,如果可以使用基于集合的替代方案,您不希望通过循环或游标执行某些操作。

【讨论】:

    【解决方案3】:

    当您运行 sql 存储过程时,似乎发生了超时(您的异常类型为 SqlException)。您需要增加 Sql 存储过程执行的超时时间,但我认为您不能使用 SqlHelper 类来做到这一点。

    您需要使用 SqlCommand 类,并在那里设置超时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 2011-08-23
      • 2013-11-23
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多