Hi all! I have this strange problem with the UltraTabControl in a production environment.
- The famous red cross... I know this is a thread related issue, but I don't find the cause. We have a central menu application from which all programs are loaded in a new threads:
Thread thread2 = new Thread(() => { Form2 f2 = new Form2(); Application.Run(f2); }); thread2.SetApartmentState(AppartmentState.STA); thread2.Start();
Once the sub-program is launched, there is no interaction between the menu and this program.
- This error occurs approximately once in the week and only by ONE user.
- At the moment the error occurs, the user is not working in the application. So it crashes when the program is in an inactive/idle state.
- We had a simular problem (red cross) earlier with the UltraStatusBar, but in that case all the users were affected. Removing the date- and time-panel from the UltraWinStatusBar resolved the problem.
Can someone give me a hint where I have to search to solve this issue? @Mike Saltzman, you perhaps? (Fan of your posts!) This is the exact error and stacktrace.
Error: Index was outside the bounds of the array.
Stack: at System.Collections.Generic.HashSet`1.SetCapacity(Int32 newSize, Boolean forceNewHashCodes) at System.Collections.Generic.HashSet`1.AddIfNotPresent(T value) at Infragistics.Win.Notifications.NotificationUIElement.AddNotificationUIElementIfPossible(UIElement parent, INotificationBadgeProvider notificationProvider) at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics, Nullable`1 zoomFactor) 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) at Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Hi Mike! I've tried your example and it is indeed the exact stacktrace and error as in our application! Super that you could make it reproducable. I still don't know why in our case it only happens by one user and almost (of always?) when the programme isn't active - user is busy in an other application. Probably something triggers a redrawn of all the forms/tabs.If we need to upgrade the version anyway, it is recommended we go to the latest version, no? Be sure to keep me informed as soon as there is a version that fixes this bug. Many thanks!
Hi Eddy,
Just FYI, now that I know what the issue is, I am able to reproduce the exception pretty reliably.
The key is that you need to force the UltraTabControl on one form to paint while another form is in the process or displaying another UltraTabControl - which is therefore painting at the same time.
I thought you might find this useful, once you get a fix, since it will allow you to verify that the fix is working.
To get the Exception, run the attached sample and click the button. This launches 20 forms with UltraTabControls, each on it's own thread. That, in itself, will not be enough. What you have to do it work it out so that the mouse ends up over a Tab (that is, the tabs on the left side where the text is) AS another form is in the process of dislpaying. That way, you end up with two tab controls painting at the same time and they both hit the HashSet at once.
So click the button and them mouse your mouse up and down the screen in the general vicinity of where the tabs are, and I can get the Exception almost every time.
WindowsFormsApp3.zip
Oops. Turns out I was wrong. Told you I was out of the loop. There are no more fixes for 19.2 being released. Looks like this will only be fixed in 20.1 and up. Sorry about the confusion. You can see the Product Life Cycle here.
I'm pretty sure we are still doing bi-weekly builds for 19.2, so you should be able to get a fix in that version. I will check and see if there's going to be any more service releases for it. I think there is one more, but I'm kinda out of the loop on that stuff. As for the cause of the problem, it's actually quite simple, and I'm kinda kicking myself for not seeing it earlier.
Earlier in this thread. I mentioned the hash set we are using as an anti-recursion flag: 'parentsInAddNotificationUIElementIfPossible'Well... what I failed to notice is that this flag is static, as is the AddNotificationUIElementIfPossible method. This is one of the sneakier gotchas in C# - static variables are shared across threads. So they are essentially not thread-safe just by definition. So if your application creates two instance of the same form, or really any two forms that contain Infragistics controls on two different threads, there will always be a change that two of them will be painting simultaneously and cause this exception because both threads are trying to access the hash set at the same time. The fix is simply to mark that flag as [ThreadStatic] so that it creates a new HashSet on each thread, rather than trying to share one for all threads.I have no way to test this, of course, so I won't know for sure if it's fixed until you get it and try it out, but I'm very confident that's the issue.
Ok, we're looking foward to it! Will this become a bug-fix on our version (19.2.20192.302) or on the latest version? And if you guys manage to fix it, can you give us more details about the condition/cause of the problem? I've been searching for it for an eternity. ;-) A big thank you!