Cannot access disposed object

  • Thread starter Thread starter Amit Dedhia
  • Start date Start date
A

Amit Dedhia

Hi

I am having problem working with Timers in C++/CLI (the .NET version
of C++)

I have an application which has several forms with pictureBox controls
on it. There is a background timer executing every 250ms and it
generates a display image (using some real time data) and pastes those
on the picture box. As the picturebox was generated by main
application thread, I used 'control.Invoke()' in the timer function
for displaying the image.

The problem starts when I close the form. In Form_CLose event I
dispose the timer. And then the form also gets disposed. However, even
after this the timer function is executed at least once (it is
possible that the timer was executing when timer->dispose() was
called). This function eventually calls the control.Invoke and then I
get ObjectDisposed exception saying that 'Disposed object cannot be
accessed'. I tried using both System.Threading.Timer and
System.Timers.Timer.

Is there any solution/workaround for this?

I tried control.BeginInvoke() instead of control.Invoke().
BeginInvoke() returns immidately and the method executes
asynchroneously in a threadpool therad. This appearently solves the
issue. However I am not too sure about it.

I have, however, few doubts related to this. As the threads are
running very short intervals (250ms) is it possible that there are
more than one thread pool threads pending and the second one executes
before the first one?

Also - lets say one control.Invoke() is waiting execution in thread
pool thread. The form closes before the thread pool function executes
(the application is still alive as there are other forms). What
happens to thread pool thread then? Does it execute? If yes, what
about the exceptions (it will surely generate exception as the form is
disposed). If it does not execute, then does that threadpool thread
get recycled and be avaialble to others?
(I see that the thread count keeps increasing in my application. On
the end user machine it increases to very high value)

Please can some give me a solution and solve my queries?

Thanks in advance
Best regards
Amit Dedhia
 
Amit said:
Hi

I am having problem working with Timers in C++/CLI (the .NET version
of C++)

I have an application which has several forms with pictureBox controls
on it. There is a background timer executing every 250ms and it
generates a display image (using some real time data) and pastes those
on the picture box. As the picturebox was generated by main
application thread, I used 'control.Invoke()' in the timer function
for displaying the image.

The problem starts when I close the form. In Form_CLose event I
dispose the timer. And then the form also gets disposed. However, even
after this the timer function is executed at least once (it is
possible that the timer was executing when timer->dispose() was
called). This function eventually calls the control.Invoke and then I
get ObjectDisposed exception saying that 'Disposed object cannot be
accessed'. I tried using both System.Threading.Timer and
System.Timers.Timer.

Is there any solution/workaround for this? [...]

Please can some give me a solution and solve my queries?

This is the determinististic object deletion in a GC environment
problem.

You need to use reference counting or something to delay
disposing the form until no other threads are referencing
it. Or use state info and test the state before using
it, in a locked region of course.
 
So, Joe : So, how can I access reference-count in C#? Can you even do it in C#? I doubt it!! Is there any API even COM that I can use, test, and reset the Reference-Count of COM Objects?

Right now, I've been using IStorage in displaying the Structured Storage Tree -- for some reason, they did not release the binary file after the process is over so I cannot remove that processed file in the run-time. I need to access the context of that Reference Count to my IStorage Object so I can set it to "0" - and release the file which is to be removed. NO IDEA how to do that?!

Your help would definitely be appreciated.
 
Lena said:
So, Joe : So, how can I access reference-count in C#? Can you even do it
in C#? I doubt it!! Is there any API even COM that I can use, test, and
reset the Reference-Count of COM Objects?
Marshal.ReleaseComObject(), and in certain specialized scenarios,
Marshal.GetIUnknownForComObject(), Marshal.AddRef(), Marshal.Release().
 
Back
Top