如何最小化WPF Toolkit图表的内存使用?

时间:2011-04-09 12:14:42

标签: wpf memory-management wpftoolkit charts

我有以下情况。

有一个折线图可以一次显示10行。每行包含355个数据点。用户可以通过选择/取消选择包含数据系列的数据对象来打开和关闭每一行。

图表线条如下所示:

    <charting:LineSeries ItemsSource="{Binding DataSlot1, Mode=OneWay}"
IndependentValueBinding="{Binding X, Mode=OneWay}"
DependentValueBinding="{Binding Y, Mode=OneWay}" 
DataPointStyle="{StaticResource styleForDataSlot1}" 
IsSelectionEnabled="False" />

我将数据加载到ViewModel的10个“数据槽”中,如下所示。

数据点是结构:

public struct SimpleDataPoint
{
    public double X { get; set; }
    public double Y { get; set; }
}

ViewModel包含“数据槽”:

   private SimpleDataPoint[][] _dataSlots;

和ViewModel通过属性公开数据槽:

   public SimpleDataPoint[] DataSlot1
   {
       get { return _dataSlots[0]; }
   }

当我将数据加载到插槽中时,我会这样做:

    _dataSlots[freeSlot] = myDataProvider.GetPoints();

清除插槽中的数据:

    _dataSlots[slotToClear] = null;

每次添加/删除插槽的数据操作后,我都会调用

    OnPropertyChanged("DataSlot1"); 

问题: 如果用户长时间工作添加和删除图表的数据行,我的应用程序的内存使用量很快就会增加到大约100兆字节。

为了查找问题是否在我的代码中,我评论了OnPropertyChanged调用。内存没有上升,当然图表没有显示任何数据。

所以我认为问题是图表没有释放内存。在我执行_dataSlots [slotToClear] = null并且图表上相应的数据行消失后,内存未释放,并且在完全关闭图表所在的WPF视图后内存也不会恢复正常。

我甚至在每个dataSlots [slotToClear] = null之后尝试调用System.GC.Collect()但它没有帮助。

如何强制WPF工具包图表释放不再显示的数据系列的内存?

1 个答案:

答案 0 :(得分:1)

在我的例子中,我有一张365分的图表。该图表在其自己的用户控件ChartView中定义。主窗口看起来如此:

 <Grid x:Name="root">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
        <Button x:Name="update" Content="Update first" Click="update_Click"/>
    </StackPanel>
    <local:ChartView Grid.Row="1" />
</Grid>

按钮的事件处理程序:

    private void update_Click(object sender, RoutedEventArgs e)
    {
        this.root.Children.RemoveAt(1);
        GC.Collect();

        this.model._dataSlots[0] = myDataProvider.GetPoints(); //this.DataContext = this.model

        var v = new ChartView();
        Grid.SetRow(v, 1);
        this.root.Children.Insert(1, v);
    }

序列如下:

  1. 从可视化树中删除ChartView控件。
  2. 调用垃圾收集器。
  3. 更新视图模型。
  4. 插入新的ChartView控件。
  5. 启动后,应用程序消耗26Mb内存。 第一次更新 - 32Mb。 第二次更新 - 35Mb。

    但是下一次更新不会超过这个值,它是最大值。

    有3650点(10倍以上),数字是:52 - &gt; 68 - &gt; 88。

    我不知道如果使用10行会发生什么,但内存消耗必须低于100Mb。