Vahid
Vahid

Reputation: 5444

Clear canvas and memory wpf

I have a Canvas and I added 20000 Line objects to it as below.

for (var i = 0; i < 20000; i++)
{
    var l = new Line
    {
        X1 = 10,
        Y1 = 10,
        X2 = 10,
        Y2 = 100,
        Stroke = Brushes.White
    };

    canvas.Children.Add(l);
}

Now let's say I want to remove these lines from the Canvas. I do this like below:

canvas.Children.Clear();

But this doesn't Clear the memory and it is like the data is stuck there. So when I add another 20000 Line objects the memory just explodes after some time.

I know that Line has overhead and I shouldn't use it in the first place but my problem is now in another area. How to clear the canvas of 20000 lines and draw new ones without increasing the memory.

Upvotes: 0

Views: 3079

Answers (1)

Andy
Andy

Reputation: 6466

Are you actually sure they're not going? I've just put the following demo application together.

enter image description here

XAML

<Window x:Class="WpfApplication7.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>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas Grid.Row="0" Name="canvas" Background="Black"/>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Content="Add" Name="btnAdd" Click="btnAdd_Click" />
            <Button Grid.Column="1" Content="Remove" Name="btnRemove" Click="btnRemove_Click"/>            
        </Grid>
    </Grid>
</Window>

C#

using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfApplication7
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            for (var i = 0; i < 20000; i++)
            {
                var l = new Line
                {
                    X1 = 10,
                    Y1 = 10,
                    X2 = 10,
                    Y2 = 100,
                    Stroke = Brushes.White
                };

                canvas.Children.Add(l);
            }
        }

        private void btnRemove_Click(object sender, RoutedEventArgs e)
        {
            canvas.Children.Clear();
        }
    }
}

And check the memory usage with Ants memory profiler (http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/).

After pressing the add button and adding the lines, this is the instance list for line. enter image description here

you can clearly see the line instances in that one, then after pressing remove you can see the line instances have completely gone as well as the memory usage going down on the graph at the top.

enter image description here

Upvotes: 4

Related Questions