VB.net ApplicationFramework Plus SplashScreen: InvalidOperationException

I recently changed my application to use custom SplashScreen (it was just a timer form loading the main form and closed) in the Application Framework.

Here is what I did:

  • Created a new SplashScreenForm, which shows the version of the application, etc.
  • Selected that form on: My project → Application → SplashScreen
  • Moved long initialization code from the designer of the main form to the ApplicationEvents launch event

It completely does what I want. First, SplashScreen appears, what triggers the start event and whether it works. SplashScreen closes and the actual basic shapes appear.

So far so good. But our customers sometimes get this nasty exception during startup:

System.InvalidOperationException: Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde. bei System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle) bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) bei System.Windows.Forms.Control.Invoke(Delegate method) bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen() bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainFormLoadingDone(Object sender, EventArgs e) bei System.EventHandler.Invoke(Object sender, EventArgs e) bei System.Windows.Forms.Form.OnLoad(EventArgs e) bei System.Windows.Forms.Form.OnCreateControl() bei System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) bei System.Windows.Forms.Control.CreateControl() bei System.Windows.Forms.Control.WmShowWindow(Message& m) bei System.Windows.Forms.Control.WndProc(Message& m) bei System.Windows.Forms.ScrollableControl.WndProc(Message& m) bei System.Windows.Forms.Form.WmShowWindow(Message& m) bei System.Windows.Forms.Form.WndProc(Message& m) bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 

It seems that there was an error during HideSplashScreen (), but the fact is that the whole stack went out of my control, so I can’t just catch this exception.

Any suggestions?

+6
invoke winforms invalidoperationexception
source share
4 answers

Put it in your splash. If there are some components, this element may already be declared in the Designer.vb file. Just move its contents to the source code and paste the first line.

 Protected Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then My.Application.SplashScreen = Nothing MyBase.Dispose(disposing) End Sub 

I checked in-depth analysis, including decompiling the frame assembly, and this should do the trick. A detailed explanation will be longer.

I cannot reproduce this problem on my own computer, but the error occurs on different client computers. It seems impossible to reproduce it even with malicious calls. There is nothing to do with HW or SW to simulate a problem, but this usually happens on slow or high-performance PCs, when event cycle messages are delayed and workflows switch at the wrong time.

+5
source share
  • You can reproduce the problem (i.e., distinguish between specific scenarios in which the problem occurs and does not occur).
  • What events do you handle in the MyApplication class ?
  • Try adding the following handler to this class, maybe an exception will be found here and it will give you more information about the stack
  • When you get to the handler, check if there is an InnerException recursively, and determine if the error you see is really the original error or just a retron.
  • Disable "Just My Code" (read this for more information) and you can track the source of the problem.

NTN


 Private Sub MyApplication_UnhandledException( ByVal sender As Object, ByVal e As ApplicationServices.UnhandledExceptionEventArgs) _ Handles Me.UnhandledException Stop End Sub 
+1
source share

This is my decision. I ended up swallowing any InvalidOperationException in the UnhandledException event until SplashScreen disappears.

To do this, I added the MainFormLoadingComplete Property to my MyApplication class, which is set to true in the displayed event of my main form (the splash screen remains until the Form_Load event is processed).

I also realized that I needed to set MinimumSplashScreenDisplayTime to OnInitialize() . Hope this helps avoid the exception in the first place. But since this exception is completely random I

SplashScreen Code:

 Public Class SplashScreen Private Sub SplashScreen_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed ' Simulate InvalidOperationException Throw New InvalidOperationException End Sub End Class 

Form Code 1:

 Public Class Form1 Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown My.MyApplication.MainFormLoadingComplete = True End Sub End Class 

MyApplication Code:

 Partial Friend Class MyApplication Public Shared Property MainFormLoadingComplete As Boolean Protected Overrides Function OnInitialize(ByVal commandLineArgs As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) As Boolean ' MinimumSplashScreenDisplayTime has to be set before OnInitialize to be effective MinimumSplashScreenDisplayTime = 3000 Return MyBase.OnInitialize(commandLineArgs) End Function Private Sub MyApplication_Startup( _ ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup ' Simulate application init process System.Threading.Thread.Sleep(5000) End Sub Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException ' Swallow InvalidOperationException if the MainForm has not been shown If MainFormLoadingComplete = False AndAlso IsCausedByHideSplashScreen(e.Exception) Then ' Logging stuff... ' Prevent application exit e.ExitApplication = False End If End Sub Private Function IsCausedByHideSplashScreen(ByVal ex As Exception) As Boolean If ex.GetType Is GetType(InvalidOperationException) Then Return New StackTrace(ex).GetFrames().Count(Function(x) x.GetMethod().Name = "HideSplashScreen") > 0 Else Return False End If End Function End Class 
+1
source share

just stumbled upon this, we have the same problem using the same technique.

I'm going to try your solution, which works, but I just wanted to let you know how to reproduce it:

Our support of people spent a lot of time on this and, finally, narrowed it to the point that it only happened in Windows 7, and only happens right after launching windows from boot.

If you restart Windows, immediately start the application using this pop-up screen technique, the error will occur almost all the time.

If you restart Windows, wait a few minutes, and then run the application, you will never see an error.

I worked on this by putting (400) to sleep at the bottom of my main form load event, however some of them still saw the error, and I'm going to try your solution instead.

-one
source share

All Articles