【问题标题】:System.outofmemoryexception while displaying data from datatable to datagrid将数据从数据表显示到数据网格时出现 System.outofmemoryexception
【发布时间】:2018-12-06 07:13:48
【问题描述】:
private void newBtn_Click(object sender, RoutedEventArgs e)
{
    try
    {
        if (txtDayfind.Text == "" || txtDatefind.Text == "" || 
            txtTimefind.Text == "" || txtLatfind.Text == "" || 
            txtLongfind.Text == "" || txtAddressfind.Text == "" || 
            txtaccuracy.Text == "" || txtTypefind.Text == "")
        {
            Button button = sender as Button;
            string content = button.Content.ToString();
            foreach (DataTable table in dsr.Tables)
            {
                if (table.TableName == content)
                {
                    dataGrid1.ItemsSource = table.DefaultView;
                    dtselect = table;
                }
            }
        }
        else
        {
            dataGrid1.ItemsSource = dtselect.DefaultView;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

我正在尝试将数据从 DataTable 显示到 Datagrid,但 DataTable 包含超过 20 万行,因此它给出了 System.OutOfMemoryException。而且我无法显示数据并且应用程序停止工作。

请帮我解决System.OutOfMemoryException 这个问题。 我有一个包含多个表的数据集,当 DataTable 有小数据时它可以正常工作,但是当 DataTable 有大数据时它会消耗更多空间并给出 System.outofmemoryexception。

【问题讨论】:

  • 不要一次加载所有数据,只检索屏幕上显示的数据并使用分页来加载其余数据
  • 它是windows应用程序,我还没完成分页,请你帮我写代码。
  • AFAIU 您处于 32 位模式,您可以尝试切换到 64 位以允许您的应用使用更多内存,但无论如何我同意其他人在这里需要分页。
  • 是他们的任何其他方式,而不是分页这样做

标签: c# wpf


【解决方案1】:

如果从数据库读取数据时发生错误,那么分页是您的解决方案。

但是如果你在 WPF 将你的集合绑定到 DataGrid 并呈现它时遇到错误,你可以尝试将 DataGrid EnableRowVirtualization 属性设置为 true。如果这样做,只会呈现当前显示在屏幕上的行。

更新:我想,你不太明白,什么是分页。分页是以块(页)的形式从表中加载数据。像这样的东西(注意:我明白,纯字符串非参数化查询是邪恶的,但为了简单起见,我将使用它)。

在您的视图模型类或代码后面定义两个变量:

int pageSize;

int currentPage = 0;

当你定义一个查询字符串来加载数据时,你不只是使用

string query = "SELECT * FROM [your_table_name]";

但是

string query = $"SELECT * FROM [your_table_name] OFFSET {pageSize*currentPage} ROWS FETCH NEXT {pageSize} ROWS ONLY";

当您执行此查询时,它不会返回表中的所有记录,而是返回 pageSize 行,从 currentPage 开始

在您的界面中,您应该放置两个按钮,这将增加或减少currentPage 并加载下一页。或者可以通过页码手动移动到某个页面。这取决于您和您的应用程序设计。

【讨论】:

  • 分页我不能这样做,所以我想使用水平滚动条显示数据。
【解决方案2】:
<Viewbox Grid.Row="3" Stretch="Fill">
                <DataGrid x:Name="dataGrid1" Grid.Row="3" VirtualizingPanel.VirtualizationMode="Recycling" BorderThickness="0" VirtualizingPanel.IsVirtualizing="True" CanUserSortColumns="True" EnableRowVirtualization="True" IsReadOnly="True" CanUserResizeColumns="True" CanUserAddRows="False"  VerticalAlignment="Bottom"  HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" 
                HorizontalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" Height="600" Width="auto" ItemsSource="{Binding}" AutoGenerateColumns="False" ScrollViewer.VerticalScrollBarVisibility="Auto"   Background="#b5d2fc"  ClipboardCopyMode="IncludeHeader" SelectionMode="Extended" CanUserDeleteRows="False">
                    <DataGrid.Columns>
                        <DataGridTextColumn Width="200" Header="Day"  Binding="{Binding Day}"/>
                        <DataGridTextColumn Width="200" Header="Date" Binding="{Binding Date}"/>
                        <DataGridTextColumn Width="200" Header="Time" Binding="{Binding Time}"/>
                        <DataGridTextColumn Width="200" Header="Lat" Binding="{Binding Lat}"/>
                        <DataGridTextColumn Width="200" Header="Long" Binding="{Binding Long}"/>
                        <DataGridTextColumn Width="400" Header="Address" Binding="{Binding Address}"/>
                        <DataGridTextColumn Width="200" Header="Accuracy" Binding="{Binding Accuracy}"/>
                        <DataGridTextColumn Width="200" Header="Type" Binding="{Binding Type}"/>
                    </DataGrid.Columns>
                </DataGrid>
                </Viewbox>

我只需添加 Viewbox,如果我加载两个以上具有大量数据的文件,我的代码就可以正常工作,那么它消耗的内存也更少

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多