Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Elegant Ribbon Tech Support » Elegant.UI exceptions in forms that run on threads other than the main application thread Collapse All
Subject Author Date
Alexander Kaay Jun 14, 2010 - 9:25 AM

Hi,


I have a multithreaded WinForms application, and there are multiple windows that run on their own message pump threads, that is, the window is created with code like this (start in NewTI):


 


    Public Class LaunchSettings     Public Self As FUIFaultTable     Public Title As String     End Class

    Public Shared Function NewTI(Optional ByVal ATitle As String = "Console") As FUIFaultTable     Dim tthread As System.Threading.Thread = New System.Threading.Thread(New System.Threading.ParameterizedThreadStart(AddressOf TIStart))     Dim tsettings As New LaunchSettings     tsettings.Title = ATitle     tthread.Start(tsettings) Threading.Thread.Sleep(100)     SyncLock tsettings     Threading.Monitor.Wait(tsettings, 5000)     End SyncLock     NewTI = tsettings.Self     End Function     Private Shared Sub TIStart(ByVal ASettings As LaunchSettings)     Try     SyncLock ASettings     ASettings.Self = New FUIFaultTable     Threading.Monitor.Pulse(ASettings)     End SyncLock ASettings.Self.Text = ASettings.Title     Application.Run(ASettings.Self)     Catch ex As Exception     X.AssertSoft(False, "Unhandled Console error", Nothing, , ex)     End Try     End Sub


In other words, the calling threads creates a new thread, which runs TIStart method, which runs the message pump in Application.Run, which exits only when the window is closed. There is also a simple notification to the calling thread that the window creation process in complete.


This code is compliant with Microsoft’s guidelines, and all the methods within this form are suitably protected against cross-threaded class by InvokeRequired() ... BeginInvoke() constructs, again as prescribed by MS.


Now to the problem: when Elegant.UI components (not necessarily the Ribbon, but for example a ToggleButton) are placed on this form, Application.Run throws an occasional exception with the following stack trace (always the same, always on the message pump thread, bounces out of Application.Run in the code snippet above):


   at System.Windows.Forms.Control.get_Handle()

   at System.Windows.Forms.Control.PointToClientInternal(Point p)

   at System.Windows.Forms.Control.PointToClient(Point p)

   at Elegant.Ui.Control.PointToClient(IControlInternal control, Point point)

   at Elegant.Ui.Control.OnPreviewMouseLeave(PreviewEventArgs e)

   at Elegant.Ui.Control.Elegant.Ui.IControlInternal.InvokePreviewMouseLeave(PreviewEventArgs e)

   at Elegant.Ui.Control.TunnelPreviewEvent(IControlInternal control, PreviewEventType eventType)

   at Elegant.Ui.Control.OnMouseMove(IControlInternal control, MouseEventArgs e)

   at Elegant.Ui.Control.OnMouseMove(MouseEventArgs e)

   at System.Windows.Forms.Control.WmMouseMove(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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)


This happens infrequently, but regularly enough, when mouse is moved over the controls. Frequency tends to be the highest when the window is being closed, for example if the "X" button is clicked and the mouse is accidentally moved over one of Elegant controls. Same for application shutdown, often times an exception will be thrown around the time when Form.Close is called. Overlapped windows increase the probability.


It appears that, somehow, a mouse move event from one message pump/window is passed onto another window (which runs on a different message pump thread), and then the recipient window tries to process it, and that’s when the form throws the exception. I know of no way that the form that is running on the same message pump can throw this exception.


And lastly, to answer the question as to why do we use multiple message pumps: we have a soft real-time application that regularly spikes the CPU. Lesser important GUIs are delegated to lower priority threads, that way the critical GUI elements do not get queued up behind long updates, such as table redraws.


Thank you in advance,


-Alex


 

Alexander Kaay Jun 16, 2010 - 11:31 AM

Hi,


The fix is installed and was added to GAC with gacutil, but it has no effect. I am getting exactly the same errors with exactly the same frequency, stack traces and locatons.


It would seem to me that this is not a thread safety issue per se, this is an issue of routing the preview events from correct message pumps to correct windows, even though there may be only one thread involved.


Do you need any more information from my side?


Thanks,


-A

Alexander Kaay Jun 14, 2010 - 11:39 AM

I have another essentially similar stack trace, slightly more complete, this one happened when my application was trying to quit and close the windows, and the notable bit information here is that the main application thread was in Sleep(1000), which it does while waiting for the multithreaded windows to shut down.


System.InvalidOperationException:


{"Cross-thread operation not valid: Control ’’ accessed from a thread other than the thread it was created on."}


   at System.Windows.Forms.Control.get_Handle()

   at System.Windows.Forms.Control.PointToClientInternal(Point p)

   at System.Windows.Forms.Control.PointToClient(Point p)

   at Elegant.Ui.Control.PointToClient(IControlInternal control, Point point)

   at Elegant.Ui.Control.OnPreviewMouseLeave(PreviewEventArgs e)

   at Elegant.Ui.Control.Elegant.Ui.IControlInternal.InvokePreviewMouseLeave(PreviewEventArgs e)

   at Elegant.Ui.Control.TunnelPreviewEvent(IControlInternal control, PreviewEventType eventType)

   at Elegant.Ui.Control.OnMouseMove(IControlInternal control, MouseEventArgs e)

   at Elegant.Ui.Control.OnMouseMove(MouseEventArgs e)

   at System.Windows.Forms.Control.WmMouseMove(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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)

   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

   at System.Windows.Forms.Application.Run(Form mainForm)

   at AVue.XUILogTableMulti.TIStart(LaunchSettings ASettings)

Technical Support Jun 15, 2010 - 10:04 AM

Thank you for reporting this issue. We made some changes to the code to make PreviewXXX events thread safe. Please check the following fix (you should add it to the GAC manually). If something is wrong, just let us know.

elegant-ui-3.6-maximize-restore-button-fix.zip

Alexander Kaay Jun 16, 2010 - 11:32 AM

Hi,


 


The fix is installed and was added to GAC with gacutil, but it has no effect. I am getting exactly the same errors with exactly the same frequency, stack traces and locatons.


 


It would seem to me that this is not a thread safety issue per se, this is an issue of routing the preview events from correct message pumps to correct windows, even though there may be only one thread involved.


 


Do you need any more information from my side?


 


Thanks,


 


-A

Andre Schardong Jul 25, 2011 - 10:18 AM

Hi Alexander,

Did you solve your problem? Im getting same error msg with version 4.2

Thank you,

Technical Support Jun 18, 2010 - 5:30 AM

We made some additional fixes to improve interoperability between Elegant Ui controls in multi-thread environment. Please try out the updated assemblies.

elegant-ui-3.6-multithreading-fix2.zip

Alexander Kaay Jun 14, 2010 - 9:29 AM

Oops... I forgot the exception type, it is 



InvalidOperationException


"Control xxx accessed from a thread other than the thread it was created on."