Clearing collection in view model causes UI thread blocking for a long time

17 posts, 0 answers
  1. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 13 Apr Link to this post

    Hi,

    I have a tree structure here with currently 240,000 nodes. The nodes inisde the view model are placed in RadObservableCollection's so that Suspend/ResumeNotiffications is used during initialization. All nodes are initialized in expanded state. The first scrolling tests were horrible. But then I discovered AutoExpandItems="True" which solved the scrolling issue.

    But now I have a problem when the root RadObservableCollection of the tree is cleared. The profiled stack trace can be seen it the attachment. The UI thread of the application blocks for 40 seconds, because the TreeListView performs a sort, collapse and reset view on each (dead) node.

    Currently clearing the root node collection costs 8x more time than setting up (asynchronous) and displaying the whole structure (reset). Can I do anything about it?

  2. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 18 Apr Link to this post

    Hello Arthur,

    Thank you for the detailed explanation of the case.

    A possible solution for this case would be to set the AutoExpandItems property of the control to false just before the source collection is being cleared. Would it be possible for you to give this a try if you haven't done so already? Is the performance of the clearing operation improved?

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  3. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 18 Apr Link to this post

    Hello Stefan,

    it seems to help a bit, but the current approach is not really useable anyway in our scenario. We have a master grid where the selected item is used to fill a detail grid (the tree list view). The detail grid is not allowed to inpact much on the master grid's navigation performance (UI thread blocking on selected item changes).

    I have disabled the AutoExpandItems and the default state of a node (except the root) is collapsed now. Instead I will offer an expand all / collapse all command as an explicit step to expand a subtree with a busy indication. If it takes too long or makes the scrolling to slow, no one will use this command on huge structures. But for small and medium structures the speed should be fast enough.

    Hopefully this is accepted by the product owners because I do not have any optimization possibilities on my side. If not, I will try to sell a treelist (listbox) + gridview (flat) split approach, so that the tree structure is no longer handled by your code. We will see, what happens.

  4. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 21 Apr Link to this post

    Hi Arthur,

    Thank you for the clarification.

    The suggestion from my previous post was regarding the performance of the clearing operation of the source collection. Since you experience performance issues with the scrolling as well, you can try utilizing the ScrollMode property of RadTreeListView and set it to Deferred. However, I am not completely sure that the performance issue you are experiencing should be expected. As I understand from your description, with AutoExpandItems set to False the scrolling is affected, whereas with True value it behaves as expected. Can you please confirm this? May I kindly ask you to share some additional information regarding your setup?

    Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  5. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 24 Apr in reply to Stefan Link to this post

    Hi Stefan,

    in my scenario the view model nodes were initialized with IsExpanded = true and the IsExpanded binding was used on the TreeListView.

    Your TreeListView seems to be implemented in a way where the expanded states of the view items are realized when the view item rows come into view. It is clearly visible that the rows are first rendered collapsed an then expanded. I can remember, that the expanded state is applied delayed through BeginInvoke or something (I have opened an issue long time ago, and this was by design).

    Now I thought that this on the fly expansion causes the performance issue while scrolling. It was really not ussable with 240.000 nodes at two or three levels. So I was near giving up when I found the "AutoExpandItems" property. I have set it to true, and the scrolling problem was gone completely. I think because the view expansion state and the view model expansion state were in sync. The delayed expansion was gone.

    But then I realized that the initialization and cleanup times have increased dramatically. Looking into your sources it seems, that your code collapses all nodes from the deepest level to the heighest when the view model collections are cleared. Each collapse seems to trigger UI updates. This consumes too much time which is dependent on the number of expanded nodes. I think that "AutoExpandItems" only helps to uncover the underlying problem. The problem would (maybe) also be there, if I would expand the items manually one by one (if I had the time to).

    Btw: The deferred scrolling is not accepted by our PMs. It is a way to scroll which is not known by a default windows user. I must also admit that I have never seen a program on the market which uses deferred scrolling.

     

  6. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 24 Apr Link to this post

    OK, I have invested the time, and here is a simple project. Just change the extension to zip.

    1) Execute the exe, wait until VM generated.

    2) Try to scroll without pressing buttons => Scrolling performance issue.

    3) Press first button, wait => Scrolling performance issue gone

    4) Press second button => Clear performance issue

  7. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 26 Apr Link to this post

    Hello Arthur,

    Thank you for providing a simplified application demonstrating the problem.

    I am researching the case, but I will need some more time to come up with a statement. I will write back as soon as I have an update.

    Thank you in advance for understanding.

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  8. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 01 May Link to this post

    Hello Arthur,

    Thank you for your patience!

    After investigating the case, it indeed seems that the delay in the expansion would be an expected behavior. When expanding a given item, its hierarchy needs to be loaded as well. Then, it has to be measured and rendered. If the items are initially expanded through the AutoExpandItems property, the aforementioned logic would affect the initial loading time. Respectively, when the IsExpanded binding is used, the scrolling will be affected, as binding is evaluated on demand when scrolling.

    So, what I can suggest as a possible solution, would be to adopt the approach of using the AutoExpandItems property in conjunction with a RadBusyIndicator. Would this approach be feasible for you?

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  9. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 04 May in reply to Stefan Link to this post

    Hi Stefan,

     

    For the init phase the approach AutoExpandItems + BusyIndication would be OK, I think. The only requirement would be, that the UI thread does not block for this time and that a change to the underlying collection while the hierarchy is loaded would cancel the current hierarchy construction and restart with the new data. It does not help, if a perfect items virtualization is implemented, when at the same time the construction of the hierarchy of the expanded items blocks the UI thread for several seconds. The hierarchy must be constructed on a worker thread, while the busy indication keeps rotating. A non responsive UI is no option at any stage.

     

    The same is true for the clean up phase. Calling a Clear() on the observed collection must be executed instantly. UI blocking and even busy indication is not expected here. I have observed something interesting: Setting DataContext to null clears the view instantly in constrast to the 40 seconds when calling a Clear() on a collection in the DataContext. Why is this handled differently? This leads to hacks like wrapping the collection into local data contexts instead of clearing the collection directly, just to be able to proceed fast, when collection items are removed, in which nobody is interested in any longer.

  10. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 09 May Link to this post

    Hello Arthur,

    Thank you for the additional clarification and your cooperation regarding this topic as a whole.

    I am currently discussing the case with our development team, whether we can improve the behavior of the control and the way it handles the clearing of the source collection in particular. However, we will need a little more time for this. I will update you as soon as we have a result. Hopefully, this will be tomorrow.

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  11. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 10 May in reply to Stefan Link to this post

    All our grids are RadGridView based. And there is a high tendency that a big fraction of them is replaced by RadTreeListView over time, because most data is hierarchical in some way. It is really essential that RadTreeListView does not introduce performance drawbacks compared to RadGridView. I absolutely understand the complexity of this topic, so I wish your developers the best.

     

    If there is no possibility to solve this issues, because of histrorically growing code or assumtions of your user base how this control behaves, we will have to find alternative ways to implement our requirements. One way would be to use a ListBox based TreeListView as Master panel, and a RadGridView as slave view. This would circumvent the hierarchy construction and cleanup in your code. If this is not accepted by the product managers, we will have to evaluate other tree grids on the market, which would introduce a large bunch of work here.

  12. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 15 May Link to this post

    Hi Arthur,

    Again, thank you for the clarification.

    We are still researching the case and we will need a little more time for this. I will write back as soon as possible. Please, excuse us for this delay.

    Thank you in advance for understanding.​

    Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  13. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 15 May Link to this post

    Hi Arthur,

    After the research we made regarding the possible optimizations that can be done regarding clearing the source collection, our development team has started working on implementing a fix. We will do our best to provide it with some of the upcoming latest internal builds, but I cannot commit to a particular one. You can follow the relevant item in the Feedback Portal to get notified when its status changes: Clearing the ItemsSource collection blocks the UI for significantly long time.

    I have also updated your Telerik points as a gratitude for your cooperation.

    All the best,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  14. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 16 May Link to this post

    Hi Stefan,

    great news for the cleanup phase. It would also be really cool, if you could consider a possibility to >asynchronously< preload the hierarchy. The possibility to do so would solve the following issues:

    1) If the user sets AutoExpandItems = true, it would be possible to display the busy indicator and the tool would not block while building the initial hierarchy.

    2) If the user sets AutoExpandItems = false and IsExpanded binding delivers true for many/all items, the scrolling issue would go, because the expansion/hierarchy construction would no longer happen on demand.

    This could be an explicit method to call to not have any inpact. Something like this:

    1) IsBusy = true

    2) Modify Source Collection

    3) await PreloadAsync()

    4) IsBusy = false

  15. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 18 May Link to this post

    Hi Arthur,

    Thank you for your feedback.

    Exposing such asynchronous loading would require modifying some of the core concepts that are currently present in the data engine of the control. Moreover, as the RadTreeListView component inherits the RadGridView one, it reuses various of its functionalities. With this in mind, implementing an asynchronous loading of RadTreeListView's hierarchy would affect the functionalities of both components. As we are generally trying to avoid introducing any breaking changes, I am afraid that we cannot commit ourselves to implementing such feature request.

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  16. Arthur
    Arthur avatar
    10 posts
    Member since:
    Oct 2015

    Posted 19 May in reply to Stefan Link to this post

    Hi Stefan,

    but the hierarchy exists only in the RadTreeListView code and not in the base classes, doesn't it? In the RadGridView we do not have any performance problems so far. So it seems to be a dedicated RadTreeListView problem. All hierarchy constructions happens on the UI thread. Because this is > 200ms operation for large structures this is not good. There in no chance to stop windows from marking the application window title bar to show "Not responding" and the user thinks "What a laggy software" and the programmer cannot do anything about it.

    But it is the way it is. There is a point of no return in almost any software. If a control is not designed for responsiveness from the beginning, it is difficult to provide it afterwards. It is like establishing "security on top" :-).

  17. Stefan
    Admin
    Stefan avatar
    774 posts

    Posted 24 May Link to this post

    Hello Arthur,

    Indeed, the hierarchy is present only in RadTreeListView. Note, however, that we need to ensure that it will be working as expected in all scenarios with the functionalities that are reused from RadGridView's data engine.

    As a side note, the fix regarding clearing the source collection is already available in the latest internal build. Can you please give it a try? Is the performance of the clearing operation improved on your end?

    Best Regards,
    Stefan X1
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Back to Top