Cannot access a disposed object

38,076

Solution 1

You should post the relevant parts of your LoadImagesToFlowPreviewPanel method.

This is speculation without seeing the code, but one explanation could be:

  • LoadImagesToFlowPreviewPanel is calling Application.DoEvents in a loop

  • The Form is closed and the TreeView disposed during one of the calls to Application.DoEvents

  • But the loop continues to execute and accesses the disposed TreeView.

If it was this, the solution would be either a redesign to avoid calling Application.DoEvents, or at least checking if the Form is closed / TreeView is disposed after every call to Application.DoEvents.

UPDATE in response to comment:

Wow! Actually the LoadImages is calling the Application.DoEvents within a loop

If you use Application.DoEvents you expose yourself to reentrancy problems in your code - you need to be very careful and make sure you understand all the consequences when you use it. The issue you described is not the only problem you're likely to face. I would only use it in very specific cases where I can guarantee not to have reentrancy problems (e.g. while a modal progress dialog is displayed). And many people will call DoEvents "evil" and have nothing to do with it at all.

Solution 2

Basically this happens when you perform an operation on a object that is still alive that you have disposed. So either like this:

A a = new A();
a.Dispose();
//operations performed on a will fail now

Or like this

using( A a = new A()){
  ...
}
//operations performed on a will fail now

Remember that a using block will also dispose your object just like manually calling Dispose.

Share:
38,076
GeorgeBoy
Author by

GeorgeBoy

Updated on April 27, 2020

Comments

  • GeorgeBoy
    GeorgeBoy about 4 years

    i am facing a huge problem with the "Cannot access a disposed object. Object name: 'TreeView'." error.

    On a windows forms of mine i use a custom windows explorer object.

    And here come the code parts...

    On the selected node event, i load the images found within the selected directory to the 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
    

    On the button close event

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

    On the Form Closing event

     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
    

    While debugging i noticed that when i confirm closing the application, the code within the LoadImagesToFlowPreviewPanel sub continues to execute. The error is raised when all the images are loaded to the FlowLayoutPanel control.

    And here comes the stack trace...

       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()
    

    UPDATE: IF all the images are loaded to the FlowLayoutPanel and the confirmation of the application close comes next, i get no error.