VB.net ApplicationFramework加上SplashScreen:InvalidOperationException

Jür*_*ock 6 vb.net invoke invalidoperationexception winforms

我最近更改了我的应用程序,使用自定义SplashScreen(它只是一个带有Timer的表单,主窗体并自行关闭)到应用程序框架.

这是我做的:

  • 创建了一个新的SplashScreenForm,显示了应用程序版本等.
  • 选择该表格在:我的项目 - >应用程序 - > SplashScreen
  • 将长时间运行的初始化代码从主窗体的构造函数移动到ApplicationEvents启动事件

这完全符合我的要求.SplashScreen首先显示,而不是启动事件触发并且它是否正常工作.SplashScreen关闭,显示实际的主窗体.

到现在为止还挺好.但我们的客户有时会在启动期间遇到这个令人讨厌的异常:

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)
Run Code Online (Sandbox Code Playgroud)

在HideSplashScreen()期间似乎有一个错误,但问题是整个堆栈都不受我的控制,所以我不能只捕获这个异常.

有什么建议?

小智 5

把它放在你的飞溅中.如果有一些组件,则此子组件可能已在Designer.vb文件中声明.只需将其内容移至源代码并插入第一行即可.

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

我已经深入分析了包括框架程序集的反编译,这应该可以解决问题.详细的解释将是更长的故事.

我无法在自己的计算机上重现此问题,但在各种客户端计算机上发生错误.即使使用恶意电话,也无法重现它.模拟问题没有硬件和软件相关的条件,但是当事件循环消息被延迟并且工作线程在错误的时刻切换时,它通常发生在慢速或高CPU使用的PC上.