Unhandled IndexOutOfRangeException in LayoutLinks

Hi,

I have a diagram that I’m binding to a GraphModel<MyType, string>. I am setting NokeKeyPath, ToNodesPath, NodeCategoryPath, GroupNodePath, NodeIsGroupPath and NodesSource in order to give myself an expandable layout with links between top level nodes. These top level nodes are listed in a selector so that users can choose which ones are displayed in the diagram. 99% of the time everything works as expected, but sometimes, when I am adding / removing a lot of nodes to the model (maybe of the order of hundreds of changes at once) I receive the following exception which I can’t handle as it seems to be on a background thread:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Northwoods.GoXam.Layout.LayeredDigraphLayout.LayoutLinks()
at Northwoods.GoXam.Layout.LayeredDigraphLayout.#7.#Xw()
at Northwoods.GoXam.LayoutManager.#ig()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

Reproducing this error is tricky, but when it does occur it’s fatal as the diagram simply fails to work afterwards.

I was initially getting this error with version 1.3.5.4 of the library, but I’ve upgraded to the 2.1.0.4 beta and it’s still happening (although possibly less frequently?).

Can anyone help?

Cheers,

Karli

Is this for WPF or for Silverlight?

Are you modifying anything (Diagram or Nodes or Links) in a thread other than the “UI thread”?

Are you making all changes within a transaction?

Hi,

It’s a WPF app and I’m not modifying anything from a non-UI thread. I’ve tried with and without a transaction around the modifications, and I can replicate the bug in both cases. If anything, it seems slightly more frequent when I use a transaction.

Cheers,

Karli

The code hasn’t changed much (if at all) in a long time, so the version number probably doesn’t matter.

Even though everything is happening within one thread, there is still a lot of asynchrony. The most obvious case of this is when there is layout animation. (Diagram.LayoutManager.Animated is true by default.) So I’m wondering if the changes you are making are happening during such a time. The LayoutLinks code is executed on the “old” diagram even though some of the links have been deleted.

If you turn off animation, does it help? If you keep animation but delay your changes for at least the length of the animation, does it help?

Unfortunately there’s no way to know whether other “stuff” is queued to happen. In the specific case of layout animation, there is some internal state and a corresponding event, but it isn’t accessible. The best would be to try to do all your changes in a Diagram.LayoutCompleted event handler, but that doesn’t help when there’s no layout ongoing. As a kludge you could see if Diagram.Cursor is the Wait cursor.

Thanks - disabling animation certainly seems to have helped. I’ve been testing it quite hard, and as yet the problem hasn’t recurred. Losing animation isn’t a big deal for us, so this will do for now.

As an aside, if I were to change my code to use GraphLinksModel instead of GraphModel, would this problematic code still be called, or would it be bypassed as I’d be maintaining the links myself?

Thanks again for your help,

Cheers,

Karli

Yes, when there is layout animation, some of the layouts need to remember the desired link routings. During the layout animation, nodes are moved and the links get their default routing. At the end of the animation the link routings are applied. They have to be done at the end so that the custom routings aren’t lost due to the movement of the nodes.

But I can imagine that if you have removed some nodes and/or links during a layout animation, there might be a bug which causes the application of the custom link routes to be confused when a link doesn’t exist any more.