I have an ultragrid who's DataSource property is set to a BindingList. I'm using MVP in such a way that binding to models is the only way of communication between the view and presenter.
My app usually uses about 45-60MB of RAM. When stress testing by pulling back 50,000 rows from a database and adding them to the BindingList (one at a time since there is no AddRange on a BindingList), it causes the memory usage to fly up to 600MB - 1GB+ within a matter of seconds and then crashes with a System.OutOfMemory exception.
I thought it was due to the fact that each row has a image depending upon a value on that row. I changed all such usage of .Appearance to reuse Appearance objects I added to the Appearances collection when creating the grid, but the problem persists. I also changed to using GetCellValue instead of referencing cells.
I finally tracked it down to the fact that I call e.Row.RefreshSortPosition in InitializeRow. When I uncomment this line it only uses about 288MB of RAM. Higher than I'd like, but understandable for the ridiculous amount of data it's showing. (Ideally we need to get the user to filter better when pulling the data, but I wanted to test this scenario anyway...)
I do have columns added to the .SortedColumns to sort by, but (I may be mistaken) it seemed like rows added after the initial load (we push updates out to the client every so often) would not end up in the correct position. So I make that call to ensure that when I call BindingList.Add(item), it ends up in the right spot.
Any thoughts on why this may be happening?(I can try to create a minimal solution to re-create the issue, but didn't want to do it, if it there was a simple "just do this instead" kind of answer. I'm using v10.3.)
Hi,
I'm not sure, but my best guess is that you are calling RefreshSortPosition while the grid is in the middle of processing the rows and this is causing some recursion. For example, if the grid is already in the process of loading an initializing all of the rows, and you call RefreshSortPosition on a row inside InitializeRow, this might cause all of the rows to be re-initialized again - the whole process starts over.
Like I said, that's just a guess.
I'm not sure calling RefreshSortPosition inside of InitializeRow is a good idea in any case. It's probably best to do it outside of the events of the grid and to just call this method after you add the rows.
You are correct that the grid doesn't automatically sort new rows that are added to it after the sorting has already completed. But if you are adding 50,000 rows to your data source at once, then refreshing the sort position of each individual row one at a time inside of InitializeRow is a very inefficient way to handle it. You would be much better off waiting until all 50,000 rows are loaded and then calling band.SortedColumns.RefreshSort once.
I am having the same problem and after reading this I moved the calls to RefreshSortPosition out of InitializeRow and call it after the row has been added/refreshed instead. However, I am still having the same problem. My situation is slightly more complex (which may or may not be relevant) because I have 1000s of rows in the grid where every 4 rows have several key cells merged (using the MergeCells feature - with MergedCellStyle set to Always) and a customized sort on one of the non-key cells such that the 4 rows are always sorted together (and therefore merged). Real time updates are broadcast to the grid which may result in the placement of the 4 rows (due to the customized sort) to be changed. Hence after resetting the 4 rows, so that their data is refreshed (and InitializeRow is called), I then call RefreshSortPosition on each of the 4 rows. At this point I periodically get an OutOfMemory exception.
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Hashtable..ctor(Int32 capacity, Single loadFactor) at Infragistics.Win.UltraWinGrid.RowsCollection.RowsSortComparer..ctor(RowsCollection rows, Boolean groupingRows) at Infragistics.Win.UltraWinGrid.RowsCollection.MoveRowToCorrectSortOrder(UltraGridRow row) at Infragistics.Win.UltraWinGrid.RowsCollection.EnsureCorrectSortPosition(UltraGridRow row) at Infragistics.Win.UltraWinGrid.UltraGridRow.RefreshSortPosition()
Any ideas?
I am using v10.3
thanks