首页 > 解决方案 > 将数据加载到数据表中时出现内存异常

问题描述

我正在尝试从存储过程中获取数据,并尝试使用 Load 方法将这些数据加载到数据表中。下面是我的代码

     using (SqlConnection sqlConnection = new SqlConnection(connectionString))
        {
            DataTable addDataTable;
            using (SqlCommand orgCommand = new SqlCommand("dbo.GetTable", sqlConnection))
            {
                orgCommand.CommandType = CommandType.StoredProcedure;

                orgCommand.CommandTimeout = 0;
                sqlConnection.Open();
                using (SqlDataReader reader = orgCommand.ExecuteReader())
                {
                    addDataTable = new DataTable();
                    addDataTable.TableName = "TableName";
                    addDataTable.Load(reader);
                    dataSet.Tables.Add(addDataTable);
                }
            }
            dataGridView1.DataSource = addDataTable;

此存储过程返回大量行,并且在尝试加载数据表时,代码“addDataTable.Load(reader)”将以下内存抛出异常。是否有任何其他替代方案或任何优化技术可以将大量数据加载到数据表中?

System.OutOfMemoryException was unhandled
HResult=-2147024882
Message=Exception of type 'System.OutOfMemoryException' was thrown.
StackTrace:
   at System.Data.RBTree`1.TreePage..ctor(Int32 size)
   at System.Data.RBTree`1.AllocPage(Int32 size)
   at System.Data.RBTree`1.GetNewNode(K key)
   at System.Data.Index.InitRecords(IFilter filter)
   at System.Data.Index..ctor(DataTable table, IndexField[] indexFields, Comparison`1 comparison, DataViewRowState recordStates, IFilter rowFilter)
   at System.Data.DataTable.GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter)
   at System.Data.DataColumn.get_SortIndex()
   at System.Data.DataColumn.IsNotAllowDBNullViolated()
   at System.Data.DataTable.EnableConstraints()
   at System.Data.DataTable.set_EnforceConstraints(Boolean value)
   at System.Data.DataTable.EndLoadData()
   at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
   at System.Data.Common.LoadAdapter.FillFromReader(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
   at System.Data.DataTable.Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler)
   at System.Data.DataTable.Load(IDataReader reader)
   at WindowsFormsApplication4.Form1..ctor() in C:\Users\Anish George\Documents\Visual Studio 2015\Projects\WindowsFormsApplication4\WindowsFormsApplication4\Form1.cs:line 35
   at WindowsFormsApplication4.Program.Main() in C:\Users\Anish George\Documents\Visual Studio 2015\Projects\WindowsFormsApplication4\WindowsFormsApplication4\Program.cs:line 19
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

先感谢您。

问候, 阿尼什

标签: c#winformsperformancedatatable

解决方案


正如@SlapY 和@Barry O'Kane 已经指出的那样,随着用户的需求越来越多,您可能应该实现某种分页和/或延迟加载新数据。当您处理项目列表时,不要尝试一次加载所有内容,而是加载 X 个项目的组,其中 X 是对您的用例有意义的计数。

在使用项目列表时,请始终牢记,在大多数情况下,这些列表可能会很大。潜力我的意思是大多数时候你试图代表的事物列表没有硬性限制......(即用户数,登录数等)

例如,如果您正在为应用程序的用户创建数据表/数据网格,则必须按页面加载用户,一次 X(可能 10 个,可能 50 个,也许用户可以在某些页面大小范围之间做出决定)。如果您没有页面,而是希望在用户向下滚动时延迟加载,您将再次必须在 X 项的行中引入新数据,以保持性能和可伸缩性


推荐阅读