如何释放WPF datagrid Row的内存?

时间:2015-05-04 12:15:40

标签: c# memory memory-leaks datagrid backgroundworker

我正在使用后台工作者类来更新DataGrid中的行。它是一个无限循环,更新过程是连续的。当我继续这个时,我将得到System.OutofmemoryException。我的要求是在100k行之后,我想删除第0行并将最新的行添加到DataGrid。我能够删除行但我无法释放Datagrid Rows分配的内存。

我的要求是RAM的使用应该是恒定的,因为我们在100k行之后添加行。 (意味着如果100k行分配250000KB的内存,它应该与我们继续添加新行相同)。我该怎么做到这一点? 如何释放WPF数据网格行分配的内存?

我使用的示例代码:



<Window x:Class="TestMemLeak.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid  Name="dg1" HorizontalAlignment="Left" Margin="0,78,0,0" VerticalAlignment="Top" Height="242" Width="517" GridLinesVisibility="None" IsReadOnly="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path=sno}" ClipboardContentBinding="{x:Null}" Header="Sno"/>
                <DataGridTextColumn Binding="{Binding col1}" ClipboardContentBinding="{x:Null}" Header="Coloumn1"/>
                <DataGridTextColumn Binding="{Binding col2}" ClipboardContentBinding="{x:Null}" Header="Coloumn2"/>
                <DataGridTextColumn Binding="{Binding col3}" ClipboardContentBinding="{x:Null}" Header="Coloumn3"/>
                <DataGridTextColumn Binding="{Binding col4}" ClipboardContentBinding="{x:Null}" Header="Coloumn4"/>
                <DataGridTextColumn Binding="{Binding col5}" ClipboardContentBinding="{x:Null}" Header="Coloumn5"/>
                <DataGridTextColumn Binding="{Binding col6}" ClipboardContentBinding="{x:Null}" Header="Coloumn6"/>
                <DataGridTextColumn Binding="{Binding col7}" ClipboardContentBinding="{x:Null}" Header="Coloumn7"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="Load" HorizontalAlignment="Left" Margin="56,10,0,0" VerticalAlignment="Top" Width="75" Click="Load_Click"/>

    </Grid>
</Window>
&#13;
&#13;
&#13;

代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

 namespace TestMemLeak
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    BackgroundWorker worker = new BackgroundWorker();
   public  class test
    {
        public int sno{get; set;}
        public string col1 { get; set; }
        public string col2 { get; set; }
        public string col3 { get; set; }
        public string col4 { get; set; }
        public string col5 { get; set; }
        public string col6 { get; set; }
        public string col7 { get; set; }

    }
    public MainWindow()
    {
        InitializeComponent();
        worker.WorkerReportsProgress = true;           // For Background Worker
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerSupportsCancellation = true;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    }


    private void Load_Click(object sender, RoutedEventArgs e)
    {
        dg1.Items.Clear();
        worker.RunWorkerAsync(1000000);
    }
    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        int max = (int)e.Argument;
        for (int i = 1;i<max ;i++ )
        {
            (sender as BackgroundWorker).ReportProgress(i);
            System.Threading.Thread.Sleep(1);
        }
    }
    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

        int i = e.ProgressPercentage;
    if (i > 10000)
        {
            dg1.Items.RemoveAt(0);
            GC.ReRegisterForFinalize(dg1.Items[0]);             

        }
        dg1.Items.Add(new test() {sno=i,col1="test",col2="test",col3="test",col4="test",col5="test",col6="test",col7="test" });
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            System.Windows.MessageBox.Show("Task Cancelled.....");
        }

            // Check to see if an error occurred in the background process.

        else if (e.Error != null)
        {
            System.Windows.MessageBox.Show("Error while performing background operation." + e.Error.Message);
        }
        else
        {
            // Everything completed normally.
            System.Windows.MessageBox.Show("Task Completed..." + e.Result);
        }
    }
}}

0 个答案:

没有答案