超时时间没有过去,但仍然超时(见代码)?

时间:2009-05-11 15:25:40

标签: asp.net sql timeout

好的我在搅拌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 CODE:

<%@ 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>

3 个答案:

答案 0 :(得分:14)

从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. 互联网浏览器超时浏览器/客户端只会等待这么久。你没有控制它,所以没有必要担心它,但你应该知道它存在。
  6. 请务必查看我列出的前4个。

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

    另外,看看你的代码,我可以看到你可以把它写成一个大查询,而不是一堆小问题。这对数据库来说效率要高得多,代价是组装结果会有一些额外的复杂性,但结果会更快。但是对于那些不经常运行的东西,当你已经建立了以这种方式构建的存储过程时,你可能无法证明重写东西是合理的。

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

答案 1 :(得分:4)

当您运行sql存储过程时,看起来超时正在发生(您的异常是SqlException类型)。您需要增加Sql存储过程执行的超时,但我认为您不能使用SqlHelper类来执行此操作。

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

答案 2 :(得分:0)

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