无法访问已处置的对象

Geo*_*Boy 5 .net c# vb.net dispose winforms

我正面临一个巨大的"Cannot access a disposed object. Object name: 'TreeView'."错误问题。

在我的 windows 窗体上,我使用自定义 windows 资源管理器对象

代码部分来了……

在选定的节点事件中,我将在选定目录中找到的图像加载到 FlowLayoutPanel。

 Private Sub ExpTree1_ExpTreeNodeSelected(ByVal SelPath As String, ByVal Item As ExplorerControls.CShItem) Handles ExpTree1.ExpTreeNodeSelected
      'Loop until all images are loaded.
       LoadImagesToFlowPreviewPanel()
 End Sub
Run Code Online (Sandbox Code Playgroud)

关于按钮关闭事件

 Private Sub WizardControl1_CancelClick(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles WizardControl1.CancelClick
        Me.Close()
 End Sub
Run Code Online (Sandbox Code Playgroud)

在表单关闭事件上

 Private Sub Wizard_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
                Select Case XtraMessageBox.Show("Exit the application?", Me.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                Case Windows.Forms.DialogResult.No
                    e.Cancel = True
                End Select
        End If
 End Sub
Run Code Online (Sandbox Code Playgroud)

在调试时,我注意到当我确认关闭应用程序时,LoadImagesToFlowPreviewPanel子程序中的代码继续执行。当所有图像都加载到 FlowLayoutPanel 控件时会引发错误。

这里是堆栈跟踪...

   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.TreeView.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.TreeView.TvnSelected(NMTREEVIEW* nmtv)
   at System.Windows.Forms.TreeView.WmNotify(Message& m)
   at System.Windows.Forms.TreeView.WndProc(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.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
   at System.Windows.Forms.Control.WmNotify(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Application.ParkingWindow.WndProc(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.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
   at System.Windows.Forms.TreeView.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.TreeView.WndProc(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(Int32 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 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at CannonUpdater.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 82
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
Run Code Online (Sandbox Code Playgroud)

更新:如果所有图像都加载到FlowLayoutPanel并且接下来确认应用程序关闭,我没有错误。

Joe*_*Joe 4

您应该发布您的相关部分LoadImagesToFlowPreviewPanel

这是没有看到代码的猜测,但一种解释可能是:

  • LoadImagesToFlowPreviewPanel 正在Application.DoEvents循环调用

  • 在调用之一期间关闭窗体并释放 TreeViewApplication.DoEvents

  • 但循环继续执行并访问已释放的 TreeView。

如果是这样,解决方案将是重新设计以避免调用Application.DoEvents,或者至少检查 Form 是否已关闭/TreeView 在每次调用后都已释放Application.DoEvents

更新回应评论:

哇!实际上 LoadImages 正在循环内调用 Application.DoEvents

如果您使用Application.DoEvents它,您将面临代码中的重入问题 - 您需要非常小心,并确保您了解使用它时的所有后果。您所描述的问题并不是您可能面临的唯一问题。我只会在非常特殊的情况下使用它,在这些情况下我可以保证不会出现重入问题(例如,当显示模式进度对话框时)。而很多人会称之为DoEvents“邪恶”,而与之根本无关。