By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,154 Members | 1,050 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,154 IT Pros & Developers. It's quick & easy.

"Cannot access a disposed object" - weird exception.

P: n/a
Hi,

//SITUATION
I got a panel control that hold a certain position on a form.
Every controls or UIs are on this panel.

At certain situation, I called dispose() method of this panel control
and change it with other panel which contains other business logic and
UI controls.

//ACTUAL CODE PRAGMENT & SYMPTOMS
//_body is a member panel control on the form control.
//And on this panel there is another panel control that holds other UI
controls.

if(_body.Controls.Count > 0)
{
_body.Controls[0].Dispose(); //always ther is only 1 child.
_body.Controls.Clear();
}
_body.Controls.Add(control);
Application.DoEvents();

This works well. But after some time ( a few seconds maybe), I got
"System.ObjectDisposedException: Cannot access a disposed object named
\"LoginForm\".

LoginForm is a control type. It's not a name of control.
And this LoginForm is on the _body.Controls[0] panel.
And LoginForm.Dispose() get called when _body.Controls[0].Dispose();
line executes.

//MY QUESTION
I have no idea how this happen. Since I call dispose(), I think there
should be no reference to panel instance.

I've tried GC.SuppressFinalize(), but not works either.

How can I fix this code? Or Is this a bug of .NET?

Any suggestion would be appreciated. TIA. :)

Regards,
Ryan
//POST SCRIPT - WHOLE ERROR MESSAGE
"System.ObjectDisposedException: Cannot access a disposed object named
\"LoginForm\".\r\nObject name: \"LoginForm\".\r\n at
System.Windows.Forms.Control.CreateHandle()\r\n at
System.Windows.Forms.Control.get_Handle()\r\n at
System.Windows.Forms.ContainerControl.FocusActiveC ontrolInternal()\r\n
at System.Windows.Forms.Form.set_Active(Boolean value)\r\n at
System.Windows.Forms.Form.WmActivate(Message& m)\r\n at
System.Windows.Forms.Form.WndProc(Message& m)\r\n at
System.Windows.Forms.ControlNativeWindow.OnMessage (Message& m)\r\n
at System.Windows.Forms.ControlNativeWindow.WndProc(M essage& m)\r\n
at System.Windows.Forms.NativeWindow.DebuggableCallba ck(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)\r\n at
System.Windows.Forms.UnsafeNativeMethods.PeekMessa ge(MSG& msg,
HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)\r\n at
System.Windows.Forms.ComponentManager.System.Windo ws.Forms.UnsafeNativeMethods+IMsoComponentManager. FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoopI nner(Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoop( Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.Application.Run(Form mainForm)\r\n at
WindowsApplication1.Form1.Main() in
c:\\src\\smart\\windowsapplication1\\form1.cs:line 88"
Jul 21 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Dispose does not remove all the references at all, it is up to you to ensure
this happens. Dispose is used to clean up an objects resources, so that they
are not held open whilst awaiting a garbage collection. That's all. So
basically, you appear to have a reference somewhere to the disposed panel,
and your code is attempting to access it and use it. Said code appears to be
attempting an operation on the panel that requires the resources you've just
disposed to be available.

Dispose - Used to manually clear up resources when object is no longer
needed.
Finalize - Used to automatically clear up resources when object is garbage
collected.

The object will only be destroyed some arbitrary time after all references
to it are cleared.

From your stack trace, it looks like set_Active is trying to set focus to
the disposed panel.

HTH

http://codingsanity.blogspot.com

"Ryan Park" <ba**@intizen.com> wrote in message
news:50**************************@posting.google.c om...
Hi,

//SITUATION
I got a panel control that hold a certain position on a form.
Every controls or UIs are on this panel.

At certain situation, I called dispose() method of this panel control
and change it with other panel which contains other business logic and
UI controls.

//ACTUAL CODE PRAGMENT & SYMPTOMS
//_body is a member panel control on the form control.
//And on this panel there is another panel control that holds other UI
controls.

if(_body.Controls.Count > 0)
{
_body.Controls[0].Dispose(); //always ther is only 1 child.
_body.Controls.Clear();
}
_body.Controls.Add(control);
Application.DoEvents();

This works well. But after some time ( a few seconds maybe), I got
"System.ObjectDisposedException: Cannot access a disposed object named
\"LoginForm\".

LoginForm is a control type. It's not a name of control.
And this LoginForm is on the _body.Controls[0] panel.
And LoginForm.Dispose() get called when _body.Controls[0].Dispose();
line executes.

//MY QUESTION
I have no idea how this happen. Since I call dispose(), I think there
should be no reference to panel instance.

I've tried GC.SuppressFinalize(), but not works either.

How can I fix this code? Or Is this a bug of .NET?

Any suggestion would be appreciated. TIA. :)

Regards,
Ryan
//POST SCRIPT - WHOLE ERROR MESSAGE
"System.ObjectDisposedException: Cannot access a disposed object named
\"LoginForm\".\r\nObject name: \"LoginForm\".\r\n at
System.Windows.Forms.Control.CreateHandle()\r\n at
System.Windows.Forms.Control.get_Handle()\r\n at
System.Windows.Forms.ContainerControl.FocusActiveC ontrolInternal()\r\n
at System.Windows.Forms.Form.set_Active(Boolean value)\r\n at
System.Windows.Forms.Form.WmActivate(Message& m)\r\n at
System.Windows.Forms.Form.WndProc(Message& m)\r\n at
System.Windows.Forms.ControlNativeWindow.OnMessage (Message& m)\r\n
at System.Windows.Forms.ControlNativeWindow.WndProc(M essage& m)\r\n
at System.Windows.Forms.NativeWindow.DebuggableCallba ck(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)\r\n at
System.Windows.Forms.UnsafeNativeMethods.PeekMessa ge(MSG& msg,
HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)\r\n at
System.Windows.Forms.ComponentManager.System.Windo ws.Forms.UnsafeNativeMethods+IMsoComponentManager. FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoopI nner(Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoop( Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.Application.Run(Form mainForm)\r\n at
WindowsApplication1.Form1.Main() in
c:\\src\\smart\\windowsapplication1\\form1.cs:line 88"

Jul 21 '05 #2

P: n/a
Hi, thanks for your resply.

My points are :

#1 Finalize() is protected member. So it's not callable by user.

#2 Attached call stack code (like set_Active) is not my code. It's CLR
execution code. I'm sure there is no reference to disposed object after
dispose() call. Since this is called by CLR, I have no idea how to fix
this problem.

#3 I want to optimize memory usage, so how can I clear up the object in
memory when I want to safely?

Again TIA

- Ryan

Jul 21 '05 #3

P: n/a
Ryan Park wrote:
#1 Finalize() is protected member. So it's not callable by user.

Correct, the finalizer is called by a dedicated finalizer thread after
an object has been collected.
#2 Attached call stack code (like set_Active) is not my code. It's CLR
execution code. I'm sure there is no reference to disposed object after
dispose() call. Since this is called by CLR, I have no idea how to fix
this problem.
Could it be that you are disposing a control that has focus? Try setting
focus to one of the controls not being removed from the form.

#3 I want to optimize memory usage, so how can I clear up the object in
memory when I want to safely?


What are you trying to optimize? The GC is generally pretty good at this
.. Unless you are wrapping an unmanaged resource such as a file or a
database connection that you need to release as quickly as possible, let
the GC just do its job.

I think what you are experiencing is a good example of how interfering
with the GC may lead to complications.

/Joakim
Jul 21 '05 #4

P: n/a
Hi, jaokim. Thanks for you reply.
#2 Attached call stack code (like set_Active) is not my code. It's CLR execution code. I'm sure there is no reference to disposed object after dispose() call. Since this is called by CLR, I have no idea how to fix this problem.
Could it be that you are disposing a control that has focus? Try

setting focus to one of the controls not being removed from the form.
I think this opinion is highly considerable. I'll check this out.

#3 I want to optimize memory usage, so how can I clear up the object in memory when I want to safely?


What are you trying to optimize?


My custom child is very heavy. And other business forms are also heavy.

So I don't want to wait the GC's unpredictable garabage collection
activity.
I want the control (or form) to be unloaded ASAP it ends up its
functionality.

The GC is generally pretty good at this . Unless you are wrapping an unmanaged resource such as a file or a
database connection that you need to release as quickly as possible, let the GC just do its job.
I thought exatly the same as you..GC is very dependable on memory
management. But there is a memory problem if I don't erase the object
manually. On every new business form loaded, the previous object is not
unloaded from memory until it is not exclusively to do so. I found this
thru monitoring the memory usage. Since the panel area embedding a
every new business forms (or controls), it should be cleared properly
at every new business sequence.

I thoght I have done this job throught Controls.Clear() but it is not.
Obviously, there is no reference about the objects, but it is not
cleared properly.

Till now, I didn't find any proper memory management method but
dispose().

So....I think maybe I'm not good enough to deal with this problem..

Any suggestion?? TIA.

-Ryan

I think what you are experiencing is a good example of how interfering with the GC may lead to complications.

/Joakim


Jul 21 '05 #5

P: n/a
> My custom child is very heavy. And other business forms are also heavy.

So I don't want to wait the GC's unpredictable garabage collection
activity.
I want the control (or form) to be unloaded ASAP it ends up its
functionality.


This would be a good (and only one of a few) place to call System.GC.Collect
().
Make sure that you have released all references to you control before doing
so.

Check out this post from Rico Mariani:
http://blogs.msdn.com/ricom/archive/...29/271829.aspx

Mujtaba.
Jul 21 '05 #6

P: n/a
> I think what you are experiencing is a good example of how interfering
with the GC may lead to complications.


When a control is removed from a control collection, never to be used again,
the correct behaviour is to dispose it - if a control has no parent then it
has nothing to dispose it so it needs to be done manually. I don't see the
point of letting it sit on the finalization queue.

Regards,
Matt
Jul 21 '05 #7

P: n/a
Hi, sorry for late posting

My problem was solved by removing the focus from control before dispose
it. I guess window object of Windows OS is not tightly coupled with
Control object in .NET.

Though solvd the problem, I'm not satisfied with this feature of .NET.
I thinks it should erase proper window handle when I call
Controls.Clear().

And thank jaokim for your advice. :)
Hope this posting help others like me.

Regards,
Ryan

Jul 21 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.