【问题标题】:Memory Out of Exception while loading data into a datatable将数据加载到数据表中时出现内存异常
【发布时间】:2018-06-04 13:59:33
【问题描述】:

我正在尝试从存储过程中获取数据,并尝试使用 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()

提前谢谢你。

问候, 阿尼什

【问题讨论】:

  • 为什么要一次加载这么多数据?展示它几乎是不可能的。为什么不实现某种分页?
  • 我同意@BarryO'Kane,您可能想要添加分页/分页,使用 TOP 和 OFFSET 或类似方法
  • 实际上,在实时使用中,我们并没有展示所有的价值。我们只是从不同的存储过程中获取值并将其存储到数据集中,最后,我们只是展示来自该数据集的过滤值。这种方法几乎适用于所有场景,但由于我认为特定机器的性能问题,它仅在某些机器上失败。有没有办法在不改变架构的情况下进行优化?
  • 虽然分页会使表单再次加载,但当用户继续按下页面向下按钮时,它会抛出相同的异常......当有太多数据需要保存时,最好不要允许打开而不先设置过滤器

标签: c# winforms performance datatable


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2018-08-24
    • 2012-06-21
    • 2020-01-30
    • 1970-01-01
    • 2020-09-02
    • 2019-07-28
    • 2017-02-01
    • 1970-01-01
    • 2013-03-23
    相关资源
    最近更新 更多