Hi,
I have an invisible button in my form. I have a timer
(System.Windows.Forms.Timer) with interval 300 ms. In the timer tick event I
check for a certain flag, and if that flag is true, the button becomes
visible (After setting the flag's status to false again).

The problem is that if the event happened and the button became visible, and
then I closed the form, and then reopened it and let the event happen again,
then the operation of making the button visible throws an exception of type
System.ObjectDisposedException.

It looks like when I reopen the form, I already haven't got the button. One
could think it's been Garbage Collected, but I'm not sure about that, because
the button is part of the form which is reopened (Form f = new Form(); ).

Can someone please explain the source of the problem and the solution?
Thanks a lot

RE: ObjectDisposedException by MortenWennevik

MortenWennevik
Wed Jul 09 01:47:00 CDT 2008

Hi,

I'm guessing the timer event is for the "old" timer and the code tries to
make the "old" button visible, which probably has been garbage collected.
Make sure you stop the timer when you close the form, and in your event code
check

if(button1.IsDisposed || button1.Disposing)
return;

--
Happy Coding!
Morten Wennevik [C# MVP]


"gol" wrote:

> Hi,
> I have an invisible button in my form. I have a timer
> (System.Windows.Forms.Timer) with interval 300 ms. In the timer tick event I
> check for a certain flag, and if that flag is true, the button becomes
> visible (After setting the flag's status to false again).
>
> The problem is that if the event happened and the button became visible, and
> then I closed the form, and then reopened it and let the event happen again,
> then the operation of making the button visible throws an exception of type
> System.ObjectDisposedException.
>
> It looks like when I reopen the form, I already haven't got the button. One
> could think it's been Garbage Collected, but I'm not sure about that, because
> the button is part of the form which is reopened (Form f = new Form(); ).
>
> Can someone please explain the source of the problem and the solution?
> Thanks a lot
>

Re: ObjectDisposedException by Patrice

Patrice
Wed Jul 09 05:08:35 CDT 2008

Looks like the timer hold a reference to a disposed button. Double check the
button you are iolding a reference to is not disposed to confirm and correct
the problem. Is the timer part of the form (if not it cold easily be the old
timer holding a reference to the previous disposed button).

If you really need help on fixing this you could likely create a bare bone
sample so that we can see the code and tell you how to correct this (but
please narrow down the code to the strict amount of code needed).

--
Patrice


"gol" <gol@discussions.microsoft.com> a écrit dans le message de groupe de
discussion : 39A02EDE-F08F-44A5-BCF4-EB6B62D35B4E@microsoft.com...
> Hi,
> I have an invisible button in my form. I have a timer
> (System.Windows.Forms.Timer) with interval 300 ms. In the timer tick event
> I
> check for a certain flag, and if that flag is true, the button becomes
> visible (After setting the flag's status to false again).
>
> The problem is that if the event happened and the button became visible,
> and
> then I closed the form, and then reopened it and let the event happen
> again,
> then the operation of making the button visible throws an exception of
> type
> System.ObjectDisposedException.
>
> It looks like when I reopen the form, I already haven't got the button.
> One
> could think it's been Garbage Collected, but I'm not sure about that,
> because
> the button is part of the form which is reopened (Form f = new Form(); ).
>
> Can someone please explain the source of the problem and the solution?
> Thanks a lot
>


Re: ObjectDisposedException by cody

cody
Wed Jul 09 06:43:55 CDT 2008

gol wrote:
> Hi,
> I have an invisible button in my form. I have a timer
> (System.Windows.Forms.Timer) with interval 300 ms. In the timer tick event I
> check for a certain flag, and if that flag is true, the button becomes
> visible (After setting the flag's status to false again).
>
> The problem is that if the event happened and the button became visible, and
> then I closed the form, and then reopened it and let the event happen again,
> then the operation of making the button visible throws an exception of type
> System.ObjectDisposedException.
>
> It looks like when I reopen the form, I already haven't got the button. One
> could think it's been Garbage Collected, but I'm not sure about that, because
> the button is part of the form which is reopened (Form f = new Form(); ).
>
> Can someone please explain the source of the problem and the solution?
> Thanks a lot
>

You must Stop() & Dispose() the timer before closing the form.
Otherwise, the timer still runs although the Form is already disposed.

Re: ObjectDisposedException by gol

gol
Thu Jul 10 02:03:01 CDT 2008

Thank you all very much for your answers,
I'll try to explain my problem in more details. The way I see it, the timer
is not the problem, and actually I don't need the timer.

I am receiving an event in a delegate. The event is received correctly, on
time, exactly as expected. As soon as receiving the event I want to make the
button visible. This didn't succeed so I thought of using a flag and a timer
(because I remember once using that method worked well for me). This didn't
solve the problem.
The basic problem remained the same: When reopening the form, and receiving
the event, the button is already disposed. I tried to change the button's
visibility in the constructor and there it succeeds also in the second time.
(There is no exception).

I thought about it a lot, and there is something that I want to ask if this
may cause this problem. In the class where I receive the event I also have an
instance of the class that fires the event. However, it's defined as static.
So I think that on the second time of event firing, it's still the first
firing class trying to fire the event to the second receiving class, in which
it is not defined. Is this true?
Is there a way to keep that instance static and make the other things work
correctly?

What bothers me regarding this is that I use the same event receiving
mechanism for a different event and it works perfect. And another thing that
I don't understand- suppose I am using the timer, after entering the
timer_tick event handler the button should be the one that belongs to the
instance of the class that is now running, regardless of the event firing
class. Is this true?

I forgot to mention that I work in .Net Compact Framework 2.0.

Thank you all very much


"cody" wrote:

> gol wrote:
> > Hi,
> > I have an invisible button in my form. I have a timer
> > (System.Windows.Forms.Timer) with interval 300 ms. In the timer tick event I
> > check for a certain flag, and if that flag is true, the button becomes
> > visible (After setting the flag's status to false again).
> >
> > The problem is that if the event happened and the button became visible, and
> > then I closed the form, and then reopened it and let the event happen again,
> > then the operation of making the button visible throws an exception of type
> > System.ObjectDisposedException.
> >
> > It looks like when I reopen the form, I already haven't got the button. One
> > could think it's been Garbage Collected, but I'm not sure about that, because
> > the button is part of the form which is reopened (Form f = new Form(); ).
> >
> > Can someone please explain the source of the problem and the solution?
> > Thanks a lot
> >
>
> You must Stop() & Dispose() the timer before closing the form.
> Otherwise, the timer still runs although the Form is already disposed.
>

Re: ObjectDisposedException by Patrice

Patrice
Thu Jul 10 06:52:34 CDT 2008

> The way I see it, the timer
> is not the problem, and actually I don't need the timer.

Copy your project and get rid of all that is not related to the problem...

> When reopening the form, and receiving
> the event, the button is already disposed.

So the button reference you have seems to belong to the previous from
instance. Not to the current form instance. Have you tried to stop there and
check whihc instance you are using. For example you could initialize a
random label

> [Code description]

IMO a description will never replace the actual code so that there were are
crystal clear about what your code does. Usually it's best to :
1) simplify your code to the maximum so that you can concentrate on the
problem at hand. During this process you'll likely find & fix the problem
2)if not fixed, you can then post your simple repro code so that we can see
what you are doing and why it fails

It's crucial to NOT cut/paste your current code that likely contains details
that are irrelevant to the problem (making most people unwilling to browse
through the whole code to pick the relevant lines) but to post the smallest
amount of working code that shows the problem...

--
Patrice





Re: ObjectDisposedException by gol

gol
Wed Jul 16 02:24:04 CDT 2008

Hi,
This is my code:

namespace MyAPP
{
public delegate void MyDelegateDel(object sender, MyEventArgs e);

public partial class A : Form
{
public static B b;

private static MyDelegateDel DataHandler;

public A()
{
if (DataHandler == null)
{
DataHandler = new MyDelegateDel(Data_Event);
}

if (b == null)
{
b = new B();
b.ReceivedEvent += DataHandler;
}
}

public void Data_Event(object sender, MyEventArgs e)
{
if (e.MyParam == 20)
Button1.Visible = true;
}
}

public class B
{
public event MyDelegateDel ReceivedEvent;

public B()
{
}

private void SomeMethod()
{
MyEventArgs e = new MyEventArgs();
e.MyParam = 10;
ReceivedEvent(this, e);
}

private void AnotherMethod()
{
MyEventArgs e = new MyEventArgs();
e.MyParam = 20;
ReceivedEvent(this, e);
}

}
}

Thank you very much for your help

"Patrice" wrote:

> > The way I see it, the timer
> > is not the problem, and actually I don't need the timer.
>
> Copy your project and get rid of all that is not related to the problem...
>
> > When reopening the form, and receiving
> > the event, the button is already disposed.
>
> So the button reference you have seems to belong to the previous from
> instance. Not to the current form instance. Have you tried to stop there and
> check whihc instance you are using. For example you could initialize a
> random label
>
> > [Code description]
>
> IMO a description will never replace the actual code so that there were are
> crystal clear about what your code does. Usually it's best to :
> 1) simplify your code to the maximum so that you can concentrate on the
> problem at hand. During this process you'll likely find & fix the problem
> 2)if not fixed, you can then post your simple repro code so that we can see
> what you are doing and why it fails
>
> It's crucial to NOT cut/paste your current code that likely contains details
> that are irrelevant to the problem (making most people unwilling to browse
> through the whole code to pick the relevant lines) but to post the smallest
> amount of working code that shows the problem...
>
> --
> Patrice
>
>
>
>

Re: ObjectDisposedException by gol

gol
Wed Jul 16 08:01:00 CDT 2008

Thank you very much,
Is there a way I can leave
this line as is:
public static B b;
Thanks

"Patrice" wrote:

> Just suppress the "static" keyword before both members and it should
> work....
>
> A delegate is basically a function pointer. It won't automatically point to
> a new instance by using the name of the function (it looks like you expect
> it dynamically binds to the function for the current instance ?). When
> stored you just store a pointer to a function that is resolved once for all
> and it will be kept unchanged unless you are telling otherwise so here
> you'll point to the function that belongs to the first instance and only
> this one. So when disposed and using a new instance, it is unchanged and
> still try to work with the first instance...
>
>
>
> --
> Patrice
>
>
> "gol" <gol@discussions.microsoft.com> a crit dans le message de groupe de
> discussion : D277F1D0-D564-41B5-8DE8-6270013E3F1F@microsoft.com...
> > Hi,
> > This is my code:
> >
> > namespace MyAPP
> > {
> > public delegate void MyDelegateDel(object sender, MyEventArgs e);
> >
> > public partial class A : Form
> > {
> > public static B b;
> >
> > private static MyDelegateDel DataHandler;
> >
> > public A()
> > {
> > if (DataHandler == null)
> > {
> > DataHandler = new MyDelegateDel(Data_Event);
> > }
> >
> > if (b == null)
> > {
> > b = new B();
> > b.ReceivedEvent += DataHandler;
> > }
> > }
> >
> > public void Data_Event(object sender, MyEventArgs e)
> > {
> > if (e.MyParam == 20)
> > Button1.Visible = true;
> > }
> > }
> >
> > public class B
> > {
> > public event MyDelegateDel ReceivedEvent;
> >
> > public B()
> > {
> > }
> >
> > private void SomeMethod()
> > {
> > MyEventArgs e = new MyEventArgs();
> > e.MyParam = 10;
> > ReceivedEvent(this, e);
> > }
> >
> > private void AnotherMethod()
> > {
> > MyEventArgs e = new MyEventArgs();
> > e.MyParam = 20;
> > ReceivedEvent(this, e);
> > }
> >
> > }
> > }
> >
> > Thank you very much for your help
> >
> > "Patrice" wrote:
> >
> >> > The way I see it, the timer
> >> > is not the problem, and actually I don't need the timer.
> >>
> >> Copy your project and get rid of all that is not related to the
> >> problem...
> >>
> >> > When reopening the form, and receiving
> >> > the event, the button is already disposed.
> >>
> >> So the button reference you have seems to belong to the previous from
> >> instance. Not to the current form instance. Have you tried to stop there
> >> and
> >> check whihc instance you are using. For example you could initialize a
> >> random label
> >>
> >> > [Code description]
> >>
> >> IMO a description will never replace the actual code so that there were
> >> are
> >> crystal clear about what your code does. Usually it's best to :
> >> 1) simplify your code to the maximum so that you can concentrate on the
> >> problem at hand. During this process you'll likely find & fix the problem
> >> 2)if not fixed, you can then post your simple repro code so that we can
> >> see
> >> what you are doing and why it fails
> >>
> >> It's crucial to NOT cut/paste your current code that likely contains
> >> details
> >> that are irrelevant to the problem (making most people unwilling to
> >> browse
> >> through the whole code to pick the relevant lines) but to post the
> >> smallest
> >> amount of working code that shows the problem...
> >>
> >> --
> >> Patrice
> >>
> >>
> >>
> >>
>

Re: ObjectDisposedException by Patrice

Patrice
Thu Jul 24 12:55:26 CDT 2008

Yes but then don't to the b==null test so that you always have the current
instance referenced from your static variable. This introduces also a risk
or design flaw (you basically have a global reference on something that
could be still be disposed if you closed the form and didn't opened another
one. You could perhaps set b to null when closing the form to easily catch a
problem...

You may want also to explain what you are trying to do in a new discussion
thread so that one could suggest an alternative approach...

--
Patrice


"gol" <gol@discussions.microsoft.com> a écrit dans le message de groupe de
discussion : 91625B0E-44AB-406E-8500-747871D5EAA3@microsoft.com...
> Thank you very much,
> Is there a way I can leave
> this line as is:
> public static B b;
> Thanks
>
> "Patrice" wrote:
>
>> Just suppress the "static" keyword before both members and it should
>> work....
>>
>> A delegate is basically a function pointer. It won't automatically point
>> to
>> a new instance by using the name of the function (it looks like you
>> expect
>> it dynamically binds to the function for the current instance ?). When
>> stored you just store a pointer to a function that is resolved once for
>> all
>> and it will be kept unchanged unless you are telling otherwise so here
>> you'll point to the function that belongs to the first instance and only
>> this one. So when disposed and using a new instance, it is unchanged and
>> still try to work with the first instance...
>>
>>
>>
>> --
>> Patrice
>>
>>
>> "gol" <gol@discussions.microsoft.com> a crit dans le message de groupe de
>> discussion : D277F1D0-D564-41B5-8DE8-6270013E3F1F@microsoft.com...
>> > Hi,
>> > This is my code:
>> >
>> > namespace MyAPP
>> > {
>> > public delegate void MyDelegateDel(object sender, MyEventArgs e);
>> >
>> > public partial class A : Form
>> > {
>> > public static B b;
>> >
>> > private static MyDelegateDel DataHandler;
>> >
>> > public A()
>> > {
>> > if (DataHandler == null)
>> > {
>> > DataHandler = new MyDelegateDel(Data_Event);
>> > }
>> >
>> > if (b == null)
>> > {
>> > b = new B();
>> > b.ReceivedEvent += DataHandler;
>> > }
>> > }
>> >
>> > public void Data_Event(object sender, MyEventArgs e)
>> > {
>> > if (e.MyParam == 20)
>> > Button1.Visible = true;
>> > }
>> > }
>> >
>> > public class B
>> > {
>> > public event MyDelegateDel ReceivedEvent;
>> >
>> > public B()
>> > {
>> > }
>> >
>> > private void SomeMethod()
>> > {
>> > MyEventArgs e = new MyEventArgs();
>> > e.MyParam = 10;
>> > ReceivedEvent(this, e);
>> > }
>> >
>> > private void AnotherMethod()
>> > {
>> > MyEventArgs e = new MyEventArgs();
>> > e.MyParam = 20;
>> > ReceivedEvent(this, e);
>> > }
>> >
>> > }
>> > }
>> >
>> > Thank you very much for your help
>> >
>> > "Patrice" wrote:
>> >
>> >> > The way I see it, the timer
>> >> > is not the problem, and actually I don't need the timer.
>> >>
>> >> Copy your project and get rid of all that is not related to the
>> >> problem...
>> >>
>> >> > When reopening the form, and receiving
>> >> > the event, the button is already disposed.
>> >>
>> >> So the button reference you have seems to belong to the previous from
>> >> instance. Not to the current form instance. Have you tried to stop
>> >> there
>> >> and
>> >> check whihc instance you are using. For example you could initialize a
>> >> random label
>> >>
>> >> > [Code description]
>> >>
>> >> IMO a description will never replace the actual code so that there
>> >> were
>> >> are
>> >> crystal clear about what your code does. Usually it's best to :
>> >> 1) simplify your code to the maximum so that you can concentrate on
>> >> the
>> >> problem at hand. During this process you'll likely find & fix the
>> >> problem
>> >> 2)if not fixed, you can then post your simple repro code so that we
>> >> can
>> >> see
>> >> what you are doing and why it fails
>> >>
>> >> It's crucial to NOT cut/paste your current code that likely contains
>> >> details
>> >> that are irrelevant to the problem (making most people unwilling to
>> >> browse
>> >> through the whole code to pick the relevant lines) but to post the
>> >> smallest
>> >> amount of working code that shows the problem...
>> >>
>> >> --
>> >> Patrice
>> >>
>> >>
>> >>
>> >>
>>