Menu

RefreshSelectedObjects() hangs with 100,000 objects

James King
2021-07-04
2021-07-07
  • James King

    James King - 2021-07-04

    I've got a small function that allows the user to modify all selected rows with a single choice
    works fine for most usage, selecting 20 or 50 or 1000 rows or whatever

    this is a simple OLV with no images, it's not a treeview or a datalistview or anything, it's just a simple objectlistview with about 7 columns, a handful of simple delegates to handle string formatting, row grouping, a filter, and there is one editable cell which edits with a dropdown selection box

    there is also a context menu with "select all" and a couple of options to modify all selected rows with one of several values (the same as choosing the same dropdown selection for each row). as I said it works fine for smaller selections

    I've got a situation today with 100,000 rows and it's got problems

    clicking "select all" in the context menu takes about 2 seconds to complete the selection - OK
    clicking "modify selected" starts the function that iterates through SelectedObjects and updates each object accordingly, and this also takes about 2 seconds to complete - OK

    this code then ends with "olv.RefreshSelectedObjects()" and this is where it hangs, the entire GUI hangs and it takes around 30-40 minutes for this to complete. it does eventually come back to life with the new data visible, but this is clearly not in a useable condition. I can comment out this line and the entire function completes in a few seconds but obviously the olv is a mess after

    what can I do about this?

     
  • code shark

    code shark - 2021-07-07

    hi James,

    i know this issue all too well. there is a performance bug in the objectlistview when calling RefreshObject() or RefreshSelectedObjects(). on a large number of objects (100k, 1M) it can take seconds, minutes to finish. i have found a workaround that seems to work fine (at least for me):
    calling RefreshItem() instead of RefreshObject(). what i do is call olv.ModelToItem() on the model object in order to get the matching OLVListItem, and then use that OLVListItem object on the call to RefreshItem(). calling ModelToItem() + RefreshItem() takes ~100-200 micro-seconds regardless of the size of the list, so it's very fast.

    i suggest you do the same. loop through the selected items (olv.SelectedItems) and call olv.RefreshItem() on each selected item. you can also call olv.Refresh() to refresh the entire olv.
    another option: loop through the selected objects (olv.SelectedObjects) and call
    olv.ModelToItem() + olv.RefreshItem() on each selected object.

    if this doesn't work, please attach your project here so it will be easier for me to help you.

    Amit.

     

Log in to post a comment.