I have found exceptions reported in our application specific Event log that are related to the UltraWinTree and/or the UltraTreeNode. At this point I have not been able to reproduce it but it appears in the log daily and I hoping someone might be able to suggest a possible cause. Here's the stack trace:
Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4
Exception Type: NullReferenceException
Message: Object reference not set to an instance of an object.
Stack Trace:
at Infragistics.Win.UltraWinTree.UltraTreeNode.get_IsLastViewableSibling()
at Infragistics.Win.UltraWinTree.NodeClientAreaUIElement.ShouldDrawVerticalConnectorToBottom(TreeNodeUIElement nodeUI)
at Infragistics.Win.UltraWinTree.NodeClientAreaUIElement.PositionChildElements()
at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
at Infragistics.Win.UIElement.VerifyChildElements(Boolean recursive)
at Infragistics.Win.UIElement.VerifyChildElements()
at Infragistics.Win.UltraWinTree.UltraTreeUIElement.PositionChildElements()
at Infragistics.Win.ControlUIElementBase.VerifyIfElementsChanged(Boolean verify, Boolean syncMouseEntered)
at Infragistics.Win.ControlUIElementBase.get_CurrentCursor()
at Infragistics.Win.UltraControlBase.get_Cursor()
at Infragistics.Win.UltraWinTree.UltraTree.get_Cursor()
at System.Windows.Forms.Control.WmSetCursor(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
We are using version 9.2.20092.2083 of the WinForms controls.
One other thing, is that I am using one of my personal accounts to report this. The company that I work for has valid licenses for this software but the developer responsible for the licenses information and who usually would post question/help requests is no longer associated with the company. I don't currently have an account associated with those licenses (or his account information), how would I go about creating an account that associates me with the company's licenses?
Some additional information, I ran this through RedGate's Performance Profiler and found that an EndUpdate on the UltraWinTree seems to initiate the call stack that leads to this exception; although the exception did not occur when I was diagnosing this.
The EndUpdate is executed in a method that is Invoked in the finally of a try/catch/finally within a data retrieval method that is executed in a thread.
I suppose that the call stack from the posted exception may also result from some other action but the only occurrence of a call to get_IsLastVisibleSibling that I can find comes after our explicit call to EndUpdate.
jcmercure said:The EndUpdate is executed in a method that is Invoked in the finally of a try/catch/finally within a data retrieval method that is executed in a thread.
This sounds like it might be the problem right here. Is your tree bound to a data source? If so, you cannot modify or access the data source on another thread. If you have a data retrieval method that is retrieving data on another thread and updating the data source that the tree is bound to, it's certain to cause problems just like the one you are having because things will get out of synch.
I took a look at the property where the exception is occurring (IsLastViewableSibling) and nothing has been changed in this code since 2005, so it seems unlikely that there's a bug here and no one noticed it until now.
I have one other question. Other than an EndUpdate on the tree, is there anything other action on the tree that may have caused it to take that code path?
Yes, there sure is. This code will get hit any time the tree paints when one of it's UIElements has been marked dirty. So basically, this code gets call any time anything is changed in the tree and the tree paints.
What constitutes dirtying a node? For instance would a tag on a node or changing nodes key (not display text) dirty the node and require a refresh of the tree.
I have finally encountered in this in the development environment, but the steps are not readily reproducible. All I can say is it happens when the tree is re-populated, but not every time. I can re-populate the tree 20 times and then on the 21st with the same data it will fail. The next time I encounter may be after re-populating the tree 6 times.
While examining the code I did find that we are initiating a BeginUpdate from inside our retrieval thread and I am changing this to be invoked. For testing purposes I wrapped the BeginUpdate with a try/catch to see if this was explicitly the location that was blowing up, but nothing is caught here and the exception is still raised and reported.
Can starting the BeginUpdate in the data retrieval thread and updating the tree from the GUI thread via properly invoked calls result in the behavior seen?
Dirtying a UIElement typically occurs when anything that might potentially affect the UIElements drawing or positioning occurs.
So setting the Tag on a node will probably not do it. Setting the Key might, since the node will display the key whenever it's Text is not set.
jcmercure said:While examining the code I did find that we are initiating a BeginUpdate from inside our retrieval thread and I am changing this to be invoked.
If the retrieval thread is not performing any operations on the tree, then why call BeginUpdate on it? That doesn't seem to make sense unless something else the thread is doing is causing the tree to repaint.
jcmercure said:For testing purposes I wrapped the BeginUpdate with a try/catch to see if this was explicitly the location that was blowing up, but nothing is caught here and the exception is still raised and reported.
That's not really a good test. If the issue is caused by a threading problem, then the actual exception will occur long after the thing that caused the problem happened. This is why debugging threading issues is so difficult.
jcmercure said:Can starting the BeginUpdate in the data retrieval thread and updating the tree from the GUI thread via properly invoked calls result in the behavior seen?
Yes, it certainly could. But the fact that your other thread is doing this at all should be a matter of concern. BeginUpdate tells the tree not to paint itself. Why would your code be doing this unless you expected something else that occurred after that to cause the tree to be dirtied?
Sorry, for the late follow up, I was on vacation and I am just getting back to this issue.
I understand the BeginUpdate comments and I'll investigate this some more. There are no comments in the code to explain when the BeginUpdate is present other than to say it improves the tree population. The way the retrieval thread works is that it queries the the data and then loops through the returned rows creating nodes for each row. The node creation and adding it to the tree from within the retrieval thread appears to happen via Invoked methods only, but I could be missing something.
While testing this in the development environment I believe I noticed a cause for this behavior but I am trying to confirm through my users. I am able to initiate the retrieval thread repeatedly 20 times or 80 times and the exception never occurs. However, if I initiate the the retrieval and while it is running I move the mouse pointer over the tree, the exception will be thrown within a handful of attempts. I assumed this might be due to the attempt to display tool tips before the tree update is completed, but I turned the tool tips off and that did not correct the behavior.
So my question is, does the tree or tree node have any type of code that is executed on a mouse enter or mouse hover event that might initiate a call to the code that redraws the tree and its nodes?
Other than code for a double click we have no code tied to mouse events for the tree or it nodes. I have also not found code elsewhere for mouse events that might initiate a change in the tree.
If I have time I will attempt to build a sample application to test this, but it likely won't be this week.
Phalbert said:I'm updating the control on a background thread using invoke and in most case it works, but occasionally it just crashes.
What exactly are you doing on the background thread? If your background thread is modifying the DataSource of any control (grid, tree, or any other control that is bound to it), then there is absolutely no way that your code can be safe.
Using an Invoke is not enough, because you are not in control of the communication between the bound control and the data source. There will be all sorts of things happening between the data source, the BindingManager, and the bound control that you cannot invoke because they happen automatically.
Hello
I'm getting this exact same random problem. Can update 20 time no worries, and then for no reason it crashes and throws an application exception.
I'm updating the control on a background thread using invoke and in most case it works, but occasionally it just crashes.
I replaced the tree with a grid and there's no crashing problem, so it's only the Tree that is causing the problem. I can't use the grid because it does not give me the layout i need...
I notice the problem is an "Object reference not set to an instance of an object." exception and not a 'Cross thread" exception, so I was wondering if further examination was required around what could create a NULL reference in your code base given the call stack.
My stacktrace is below. Any help greatly appreciated.
STACK TRACE
Object reference not set to an instance of an object.
Source Assembly: Infragistics2.Win.UltraWinTree.v10.3
Method: get_IsLastViewableSibling
at Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics)
at Infragistics.Win.UIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics)
at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics)
at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize)
at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode)
at Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe)
at Infragistics.Win.UltraWinTree.UltraTree.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
Hi,
jcmercure said:I know you stated earlier that nothing changed in the particular code where the problem was occurring, but what about the code that called it.
That's almost certainly the case, of course. Obviously something here has changed. But without being able to duplicate the issue, there's very little we can do to determine what changed may have caused it. And... if this is a threading issue, as I suspect, then it was probably sheer luck that it used to work in the old version.
Of course, there is always the possibility that I could be wrong and that this is not thread-related. But everything you are describing here has all the hallmarks of a threading issue.
Anyway, I'm afraid I cannot really isolate the changes from 8.2 to 9.2, as there are quite a large number of changes, so as I said, there's really not way to determine which change may have introduced this issue unless we can duplicate it.
Since you have so far been resistant to sending us a sample, I am assuming that it's probably pretty tough for you to do so. Your project is probably large and complex and includes references to data sources that we obviously don't have. But if you can't reduce the project down to something really small, then we could try to take a look at a larger project, assuming of course, that we can actually run it. So maybe you could try making a copy of your project and pointing it to some dummy data source, like an UltraDataSource or a DataTable you create in code with some fake data in it, just to repro the problem in a sample we can run.
I understand that this looks like a threading problem and I will continue to look through our code; although I have been through it twice now.
Wednesday last week I rolled back the NetAdvantage controls from version 9.2 to 8.2 because the upgrade appeared to be tied to some other problems we were having with your grid. As it turns out the grid is not causing the other problem.
With the controls rolled back to 8.2, I tested the tree problem described above and found that I had been unable to duplicate the problem. I decided to put this in production and our users who had been having the tree problem every day have not seen the problem since I rolled back the controls. These errors had been being caught and reported in our event log and I have not seen an entry for this problem since the controls were rolled back.
I know you stated earlier that nothing changed in the particular code where the problem was occurring, but what about the code that called it. Something has obviously changed in your code between 8.2 and 9.2 that is causing our users to experience the problem. I found that I could reproduce the problem by moving the mouse over the tree while the tree was refreshing. Was there a code change dealing with the mouse events in your code between versions 8.2 and 9.2.
We actually need to be at 9.2 because there is a 9.2 for a combo box bug that we reported earlier this year, but the tree problem we are experiencing is a bigger concern right now and so for the moment we will stick with the 8.2 roll back.
Everything you are describing here is just getting more and more consistent with a threading problem.
To answer your question - yes, move the mouse over the tree can certainly cause element in the tree to get invalidated and those elements might attempt to access properties of the node which may be out of synch if the nodes are being modified from another thread.
My advice to you would be to examine your data retrieval code very thoroughly and make sure that nothing it is doing could possibly have any effect on the tree control and is not being invoked to the UI thread.