在C#内存问题中对大型gridview进行排序

时间:2014-12-22 16:08:56

标签: c# asp.net session gridview

我的老人'程序员将网格数据存储在会话变量中,以便对其进行排序。

我们每隔一天都要重启我们的服务器,因为它开始挂起。我觉得这是因为所有这些Session变量都在内存中浮动。

这是排序数据的最佳方式吗?有最好的做法吗?我们必须使用存储过程,因为这是他的规则。 Web应用程序非常慢,而且我对 SQL 的了解不足以帮助加快它的速度。

是否有关于会话变量的想法?还有更好的方法吗?

负荷数据方法

SqlConnection conn = new SqlConnection (ConfigurationManager.AppSettings ["ConnectionString"].ToString ());
SqlCommand cmd = conn.CreateCommand ();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "RandomStoredProdcedureName";
try 
{
    DataTable GridData = new DataTable ();
    conn.Open ();
    using (SqlDataAdapter Sqlda = new SqlDataAdapter (cmd)) 
    {
       Sqlda.Fill (GridData);
    }
    //Persist the table in the Session object. (for sorting)
    Session ["GridData"] = GridData;

    gvDetails.DataSource = GridData;
    gvDetails.DataBind ();
}
catch (Exception ex) 
{
    Removed for brevity 
} 
finally 
{
    if (conn != null) {
    conn.Close ();
}
}

排序方法

protected void gvDetails_Sorting (object sender, GridViewSortEventArgs e) {
            //Retrieve the table from the session object.
            DataTable GridData = Session ["GridData"] as DataTable;

            if (GridData != null) {

                //Sort the data.
                GridData.DefaultView.Sort = e.SortExpression + " " + GetSortDirection (e.SortExpression);
                gvDetails.DataSource = GridData;
                gvDetails.DataBind ();
            }
        }

4 个答案:

答案 0 :(得分:1)

用户不可能查看比网格显示的行数更多的记录 - 如果您的网格有25行,则超过25行的任何内容都会浪费内存/ CPU时间来处理。 (请记住,这些数字不是绝对的 - 某些应用程序可能需要更多行,有些可能需要更少。这还取决于用户查看数据并理解数据的程度。有些用户工作得更好一次只有几行,有些需要很多行 - 这甚至可能是用户的偏好,但最重要的是拉动一个巨大的结果集几乎总是浪费。)

您不应该在给定时间从数据库中提取更多数据,而不是可以在网格中显示的行数。排序应该在数据库中完成,因此您只能返回实际需要的行子集。这可以最大限度地减少Web服务器和数据库服务器之间的网络流量,并最大限度地减少Web服务器上的内存使用,因为您只将数据存储在实际需要的视图/会话状态中。

如果您使用视图状态来存储数据(这比使用Session更好,因为只有当用户查看带有网格的特定页面时才存储数据),该数据将被发送浏览器 - 您还可以通过这种方式最小化Web服务器和浏览器之间的网络流量。

如果用户尝试以不同方式对数据进行排序或转向其他页面,只需重复上述过程并根据新的页面索引和/或新的排序字段获取新行。

修改

我刚刚注意到你在问题中添加了一条评论,你通常有15个用户并返回50-1000行。除非您的Web服务器内存很少(或者除非数据库中的行巨大),否则它不太可能导致内存不足错误。您是否在会话变量中存储其他大型结果集?

答案 1 :(得分:0)

我认为排序可以在SQL中完成。但我们也必须看到SP。我从不在会话中保留DataTables,我不认为这是一个好方法。

如果数据太大而无法在每次开发人员需要时从数据库中获取数据,他/她就可以创建视图并从该视图中获取数据。它会快得多

答案 2 :(得分:0)

只需使用viewstate。

ViewState["GridData"] = GridData;

如果您能告诉我们Grid的大小,它也会有所帮助吗?

答案 3 :(得分:0)

我看不到DataTable的位置,你有问题。 我的建议是做这样的事情

public void GetData()
{
    using(var conn = new SqlConnection (ConfigurationManager.AppSettings ["ConnectionString"].ToString ()))
    {
        SqlCommand cmd = conn.CreateCommand ();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "RandomStoredProdcedureName";
        conn.Open ();
        try {
        using(var GridData = new DataTable ())
        {

            using (SqlDataAdapter Sqlda = new SqlDataAdapter (cmd))
            {
                Sqlda.Fill (GridData);
            }
            //Persist the table in the Session object. (for sorting)
            Session ["GridData"] = CREATE_YOUR_OWN_OBJECTS_FROM_THE_DT(GridData);
        }


        } catch (Exception ex) {
        Removed for brevity 
        } finally {

        if (conn != null) {
        conn.Close ();
        }
        }
    }
}

当然有更好的方法可以做到这一点,然后你应该实现排序,但我敢打赌问题是IDisposable对象从来没有被处理过