1

I have a list of nodes in a tree list.

At times I turn of the sorting on columns and in order to keep the same structure/position of the nodes I copy the structure as is, put it in a list and when the deactivation of the sort is done I put back the nodie positions. This is done like this:

        List<TreeListNode> nodes = new List<TreeListNode>();
        nodes.AddRange(xtlItemList.Nodes);

        // deactivete sorting
        foreach (var c in xtlItemList.Columns) {
            c.SortOrder = SortOrder.None;
        }

        // put back node positions
        for (int i = 0; i < nodes.Count; i++)
        {
            xtlItemList.SetNodeIndex(nodes[i], i);
        }

The problem:

Is that the second loop take alot of time to execute. For 1043 nodes it takes up to 50 seconds.

I thought I could optimize it via a parallel for loop:

        int counter = nodes.Count -1;
        try
        {
            Parallel.For
                (0
                 , counter
                 , new ParallelOptions { MaxDegreeOfParallelism = 5 }
                 , (i) =>
                 {
                     try
                     {
                         xtlItemList.SetNodeIndex(nodes[i], i);
                     }
                     catch (Exception exception)
                     {

                         //throw;
                     }
                 }
                );
        }
        catch (Exception exx)
        {


        }

I am getting some weird result. most of the time the nodes in the ui disappear and at time I am getting a null reference exception which confuses me even more.

What am I missing here?

ThunD3eR
  • 3,216
  • 5
  • 50
  • 94

2 Answers2

1

Turns out that Devexpress have BeginUpdate() and EndUpdate() methods.

I used these and they optimized my tree rendering considerably. modified solution:

Instead of the parallel for I now have:

        xtlItemList.BeginUpdate();
        for (int i = 0; i < nodes.Count; i++)
        {
            xtlItemList.SetNodeIndex(nodes[i], i);
        }
        xtlItemList.EndUpdate();

Documentation:

Begin Method

End Method

ThunD3eR
  • 3,216
  • 5
  • 50
  • 94
0

I assume you are using DevExpress XtraTreeList in a Windows Forms application.

As for parallel.for, it spawns execution on multiple threads, different from the main UI thread. It is unsafe to manipulate UI controls from a non UI thread, it leads to unpredictable results:

https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls

Thread-safe calls to WPF controls

Also, I feel that parallel loops won't make it much faster as well, since process does not involve with a background work.

I'm not an expert on DevExpress UI controls, but for your real problem, you may create an extra hidden column, in your TreeList, populate it with original index values(such as 1,2,3..) and sort its nodes initially by this column. Then later you may restore your XtraTreeList again sorting by this column, as suggested here:

https://www.devexpress.com/Support/Center/Question/Details/A2372/how-to-clear-column-sorting-and-restore-the-nodes-to-their-original-order

I guess this will work much faster.

Hope this helps resolving your problem..

Cem O
  • 36
  • 4
  • I was reluctant to crate a column for storing temp data so I crated a list which I show in my code which is the same thing as your are describing. The problem is that when I am restoring the node positions (1, 2, 3), it takes time, hence the parallel for – ThunD3eR Feb 18 '19 at 08:02