Home Forums WPF controls Xceed DataGrid for WPF BindingList<>.Clear() appears to cause Memory leak

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #23693 |

    Although similar to http://forums.xceed.com/forums/ShowPost.aspx?PostID=7305 I just want to be clear that this is the same issue/will be solved by v1.2.

    I have a BindingList<> of internal business objects. These objects are dynamically created at run time. The BindingList<> is added to a DataGridCollectionView which is set to the Grid’s ItemsSource. The columns are bound to properties of the business object.

    This all works fine. The data (and number of rows) of the BindingList<> changes often during the grid’s lifetime (the grid is used to allow users to compare WindTunnel data).

    When the data changes, it is likely that all the rows of the BindingList are changed so initially I cleared the BindingList using the Clear() method and then did an Items.Refresh(). The new data is added and displayed correctly.

    However, over time the memory of the application grows and is not released during garbage collection. Looking in WinDbg there are all the business objects – even through they have been removed from the BindingList<>.

    I have been able to reduce the effect of the problem by reusing the business objects and only removing the “extra” ones as required. However, the memory still grows if the number of rows in the grid changes often.

    I am using v1.1 plus the service pack (v3.0.7273.12150). If this is solved in v1.2 then good, otherwise are there any suggestions about how to improve the memory usage of the grid as this is a problem for using the grid in our production environment.

    Imported from legacy forums. Posted by Derek (had 997 views)

    User (Old forums)
    Member
    Post count: 23064

    DerekW,

    We’ll look into this and get back to you.

    Thanks,

    Imported from legacy forums. Posted by Pascal (had 1280 views)

    Xceed Support
    Member
    Post count: 5658

    Hi Derek,

    I’ve been trying to reproduce the issue as you mentionned.

    I used version 1.1.7273.12150 of the Xceed.Wpf.DataGrid assembly. I then created a test program that:

    – Creates a BindingList<TestClass>,
    – Fills it with TestClass objects,
    – Create a DataGridCollectionView (with the BindingList<TestClass> as parameter)

    In the application, I do the following:

    – Clear the BindingList<TestClass>,
    – Fill it again with TestClass objects,
    – call DataGridControl.Items.Refresh()

    After doing that several times, I cannot see any leak… the amount if TestClass objects in the heap is aligned with actual content of the BindingList<>

    Would it be possible for you to send me a repro application so I can try to figure what the problem is?

    You can send the repro application to support@xceedsoft.com indicating it is to be forwarded to me.

    Thanks

    Imported from legacy forums. Posted by Marcus [Xceed] (had 405 views)

    User (Old forums)
    Member
    Post count: 23064

    No problem – I will try to create a test app (and hopefully be able to reproduc ethe problem) over the weekend. Difficult to extract the exact code from the app and it is quite complex.

    Imported from legacy forums. Posted by Derek (had 466 views)

    User (Old forums)
    Member
    Post count: 23064

    Marcus, I have spent a few hours with our app just looking at this problem (sorry I have not been able to get TestApp yet but normal pressures of other things). I have narrowed down what I do to cause this, so you might be able to suggest a better way

    In the c# constructor of my grid class I create a BindingList and DataGridCollectionView and assign the grid’s ItemsSource as follows:

    listGridSourceData = new BindingList<CLS_GridRowItem>();
    listGridSourceData.AllowEdit = false;
    listGridSourceData.AllowNew = true;
    listGridSourceData.AllowRemove = true;
    dataGridCollectionView = new DataGridCollectionView(listGridSourceData);

    ItemsSource = dataGridCollectionView;

    To clear the rows from the collection I use the following:

    listGridSourceData.Clear();
    Items.Refresh();

    To Add rows to the collection I use the following:

    CLS_GridRowItem newRow = dataGridCollectionView.AddNew() as CLS_GridRowItem;

    ——-

    If I run this for a few minutes (the data changing about every 6 seconds and adding/deleting 4000 rows) the application’s memory continues to grow quite quickly.

    This morning I have tested the app logic by assigning the ItemsSource to different (empty) DataGridCollectionView (to eliminate the grid itself) and changed the Add Row to add rows directly to the BindingList by using listGridSourceData.AddNew(). In this instance the memory usage of the app is flat line with only slight rise and fall as rows are added.

    Thought I was onto something so I went back to the original code and changed the Add row to add rows directly to the BindingList but this gave the exception (similar to http://forums.xceed.com/forums/ShowPost.aspx?PostID=8112) :

    ******* Exception *********
    System.NullReferenceException

    ******* Message ***********
    Object reference not set to an instance of an object.

    ******* Stack Trace *******
    at Xceed.Wpf.DataGrid.DataGridCollectionView.AddRawItemInGroup(RawItem rawItem)
    at Xceed.Wpf.DataGrid.DataGridCollectionView.AddRawItemInGroup(IList`1 rawItems)
    at Xceed.Wpf.DataGrid.DataGridCollectionView.AddItem(Int32 startIndex, IList items, Int32 newSourceItemCount)
    at Xceed.Wpf.DataGrid.DataGridCollectionView.BindingList_ListChanged(Object sender, ListChangedEventArgs e)
    at Xceed.Wpf.DataGrid.DataGridCollectionView.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
    at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
    at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
    at Xceed.Utils.Collections.ListChangedEventManager.OnListChanged(Object sender, ListChangedEventArgs args)
    at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
    at System.ComponentModel.BindingList`1.InsertItem(Int32 index, T item)
    at System.Collections.ObjectModel.Collection`1.Add(T item)
    at System.ComponentModel.BindingList`1.AddNewCore()
    at System.ComponentModel.BindingList`1.System.ComponentModel.IBindingList.AddNew()
    at System.ComponentModel.BindingList`1.AddNew()
    at BMW.DataView.Frontend.CLS_ViewGridBaseGrid.CreateTotalNumberOfRows(Int32 iTotalRows) in C:\Projects\BMWDataView\BMWDataViewFrontend\ViewGridBaseGrid.xaml.cs:line 200
    at BMW.DataView.Frontend.CLS_ViewGridBaseGrid.AppendColumnValuesDouble(Int32 iStartRow, Int32 iColumnIndex, CLS_DataViewViewGridItemColumnFormatBase columnFormat, Boolean bAddAverageValue, Double[] dValues, Boolean bTooltipProvided, String sTooltip) in C:\Projects\BMWDataView\BMWDataViewFrontend\ViewGridBaseGrid.xaml.cs:line 668
    at BMW.DataView.Frontend.CLS_ViewGridBaseGrid.AddColumnValuesDouble(Int32 iStartRow, Int32 iColumnIndex, CLS_DataViewViewGridItemColumnFormatBase columnFormat, Boolean bAddAverageValue, Double[] dValues) in C:\Projects\BMWDataView\BMWDataViewFrontend\ViewGridBaseGrid.xaml.cs:line 631
    at BMW.DataView.Frontend.CLS_ViewGridDetail.PopulateGrid(CLS_ViewConfiguration& viewConfiguration, List`1& refDataSourceItems, CLS_DataSourceItem& refBaselineItem) in C:\Projects\BMWDataView\BMWDataViewFrontend\ViewGridDetail.cs:line 246

    Since it was said that this is fixed in v1.2 which is due any day I am happy to wait for it and see if this does fix the problem. Otherwise I will create simple test and let you have it for your analysis. If you have any other suggestions they would be much appreciated.

    Imported from legacy forums. Posted by Derek (had 927 views)

    User (Old forums)
    Member
    Post count: 23064

    Marcus – TestApp has been sent to support, marked for your attention.

    Imported from legacy forums. Posted by Derek (had 457 views)

    User (Old forums)
    Member
    Post count: 23064

    <b>This is now fixed with the latest version.</b>

    Installing the latest update (3.0.7326.14130) has allowed me to change the addition code from

    CLS_GridRowItem newRow = dataGridCollectionView.AddNew() as CLS_GridRowItem;

    to

    CLS_GridRowItem newRow = listGridSourceData.AddNew();

    (ie – adding new items directly to the BindingList). This no longer exhibits the memory leak that was evident before. The test I have carried out is to add and remove 1000 rows 300 times and the memory is consistent.

    Hence I think that teh problem was due to the work-around used to overcome the AddNew to an empty DataGridCollectionView bound BindingList.

    Imported from legacy forums. Posted by Derek (had 5501 views)

Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.