473,396 Members | 1,590 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

InvokeRequired/BeginInvoke() on Disposed control?

Hi,

I have a form that displays data (is that vague enough for you?). The
data comes in on a thread-pool thread. Since the thread pool thread is not
the same as the UI thread, the callback function of my form follows the
standard design pattern:

if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object[]{args...});
return;
}
....painting code here.....

The idea here is: If the user has closed the form (it's disposed), then
just ignore the incoming data. If the form is still open, show the data via
some painting code, but do so on the form's UI thread. Nothing too unusual
here. My question is: What happens if BeginInvoke() is called on a form that
is already disposed? This could happen in the following situation:

In the code above, let's say that the this.BeingInvoke() call is just
about to execute, but then a context switch happens and the user's request
to close the window transpires which leads to a Dispose() call on the form.
The context then switches back to my BeginInvoke() call which would then be
made against a disposed form. Is this a problem? From my perspective, I
don't care since the 'IsDisposed' check at the top of my code should catch
this... but will WinForms internally have a problem with the fact that
BeginInvoke() is being called on a form whose window handle has been
disposed?

--
Sincerely,

David Sworder
http://www.CodeFanatic.com
Nov 16 '05 #1
9 7551
David,

I don't believe this will be a problem. Basically, during a call to
Invoke/BeginInvoke, a message is sent to a window (using a window handle).
Now, that window can be your form's window, or it can be another one. This
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.

While you could check on the call before BeginInvoke to see if the form
is disposed, you should also call in the method that is passed to
BeginInvoke as well, when you are on the thread that an Invoke is not
required on. If you are disposed there, then you should not call the rest
of your code, and then exit.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"David Sworder" <ds******@cts.com> wrote in message
news:u%******************@TK2MSFTNGP12.phx.gbl...
Hi,

I have a form that displays data (is that vague enough for you?). The
data comes in on a thread-pool thread. Since the thread pool thread is not
the same as the UI thread, the callback function of my form follows the
standard design pattern:

if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object[]{args...});
return;
}
...painting code here.....

The idea here is: If the user has closed the form (it's disposed), then just ignore the incoming data. If the form is still open, show the data via some painting code, but do so on the form's UI thread. Nothing too unusual
here. My question is: What happens if BeginInvoke() is called on a form that is already disposed? This could happen in the following situation:

In the code above, let's say that the this.BeingInvoke() call is just
about to execute, but then a context switch happens and the user's request
to close the window transpires which leads to a Dispose() call on the form. The context then switches back to my BeginInvoke() call which would then be made against a disposed form. Is this a problem? From my perspective, I
don't care since the 'IsDisposed' check at the top of my code should catch
this... but will WinForms internally have a problem with the fact that
BeginInvoke() is being called on a form whose window handle has been
disposed?

--
Sincerely,

David Sworder
http://www.CodeFanatic.com

Nov 16 '05 #2
Hi,

"David Sworder" <ds******@cts.com> wrote in message
news:u%******************@TK2MSFTNGP12.phx.gbl...
Hi,

I have a form that displays data (is that vague enough for you?). The
data comes in on a thread-pool thread. Since the thread pool thread is not
the same as the UI thread, the callback function of my form follows the
standard design pattern:

if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object[]{args...});
return;
}
...painting code here.....

The idea here is: If the user has closed the form (it's disposed), then just ignore the incoming data. If the form is still open, show the data via some painting code, but do so on the form's UI thread. Nothing too unusual
here. My question is: What happens if BeginInvoke() is called on a form that is already disposed? This could happen in the following situation:
You will get a runtime exception, stating that Invoke is called on an
already disposed object.

By the way, I would do the painting in OnPaint, and just call Ivalidate if
the data arrives (which your callback signals). Invalidate triggers the
painting.
In the code above, let's say that the this.BeingInvoke() call is just
about to execute, but then a context switch happens and the user's request
to close the window transpires which leads to a Dispose() call on the form. The context then switches back to my BeginInvoke() call which would then be made against a disposed form. Is this a problem? From my perspective, I [...] --
David Sworder
http://www.CodeFanatic.com


This could lead to problems. I had this problem myself in a similar setting.
I solved it by keeping a flag to indicate whether the form is closing.
Initialize the flag to false.Make a lock object for the closing flag. In the
OnClosing handler, begin with this:

lock( closingLock )
{
isClosing = true;
}
// ... other closing code

In the callback method, execute everything guarded by the closingLock (which
is nothing more than a mutex).

lock( closingLock )
{
if( ! isClosing )
this.BeginInvoke(delegateToThisMethod, new Object[]{args...});
}

If you follow my advice, you invoke Invalidate instead of your painting
handler, and have the OnPaint handler paint based on the available data.

Cheers,
---
Tom Tempelaere
Nov 16 '05 #3
> Now, that window can be your form's window, or it can be another one.
This
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.


Another window? Which one?

David
Nov 16 '05 #4
"TT (Tom Tempelaere)" <_N_0SPA|/\|t*******@hotmail.com|/\|APS0_N_> wrote in
message news:OO*********************@phobos.telenet-ops.be...
[...]
if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object[]{args...});
return;
}
...painting code here.....

The idea here is: If the user has closed the form (it's disposed),

then
just ignore the incoming data. If the form is still open, show the data

via
some painting code, but do so on the form's UI thread. Nothing too unusual here. My question is: What happens if BeginInvoke() is called on a form

that
is already disposed? This could happen in the following situation:


You will get a runtime exception, stating that Invoke is called on an
already disposed object.


But the chance is small.
In the code above, let's say that the this.BeingInvoke() call is just about to execute, but then a context switch happens and the user's request to close the window transpires which leads to a Dispose() call on the

form.
The context then switches back to my BeginInvoke() call which would then

be
made against a disposed form. Is this a problem? From my perspective, I

[...]
--
David Sworder
http://www.CodeFanatic.com


This could lead to problems. I had this problem myself in a similar

setting.

Only, I forgot to check IsDisposed :-S. If you are really frantic about the
small chance that the form will already be closed, guard it like I did. If
you aren't then follow Nicholas' advice :-D.

---
Tom Tempelaere
Nov 16 '05 #5

"TT (Tom Tempelaere)" <_N_0SPA|/\|t*******@hotmail.com|/\|APS0_N_> wrote in
message > >You will get a runtime exception, stating that Invoke is called
on an
already disposed object.
bummer... That's what I was afraid of.
By the way, I would do the painting in OnPaint, and just call Ivalidate if
the data arrives (which your callback signals). Invalidate triggers the
painting.
good idea.
This could lead to problems. I had this problem myself in a similar setting. I solved it by keeping a flag to indicate whether the form is closing.
Initialize the flag to false.Make a lock object for the closing flag. In the OnClosing handler, begin with this:

lock( closingLock )
{
isClosing = true;
}
// ... other closing code

[...]

Excellent advice... a couple of follow ups:

Is 'closingLock' a bool value type? I don't think I'm allowed to obtain
a lock on a value type (am I?). So it sounds like the two places that I'll
want to use the lock are in the Dispose() override and in the callback...
but still, even with the lock, couldn't I end up with a situation where
BeginInvoke() is called successfully, the lock is released, Dispose() is
then called and the lock is released, then the runtime attempts to call the
delegate passed to BeginInvoke()? In that case, if the delegate is called,
my callback function would simply check 'IsDisposed' and return
immediately... but I'm wondering if perhaps .NET will have "issues" with
calling a delegate on a Form that is disposed?

Nov 16 '05 #6
"David Sworder" <ds******@cts.com> wrote in message
news:ey**************@TK2MSFTNGP10.phx.gbl...
Now, that window can be your form's window, or it can be another one.

This
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.


Another window? Which one?

David


Yeah, what if the form was the last window (e.g. main form)?

---
Tom Tempelaere
Nov 16 '05 #7
Tom and David,

If the form was the last one, then it will try and use the handle on
that form. As mentioned before, if it is Disposed, then an exception should
be thrown. However, when the form is an MDI child form, or when dealing
with a control, the window handle that the message is sent on is not always
the handle that is associated with the control.

Which control is dependent on the parent of the Form/Control.

The reason for this behavior is that the Form class's implementation of
Invoke/BeginInvoke is inherited from Control.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"TT (Tom Tempelaere)" <_N_0SPA|/\|t*******@hotmail.com|/\|APS0_N_> wrote in
message news:76********************@phobos.telenet-ops.be...
"David Sworder" < > wrote in message
news:ey**************@TK2MSFTNGP10.phx.gbl...
Now, that window can be your form's window, or it can be another one.

This
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.


Another window? Which one?

David


Yeah, what if the form was the last window (e.g. main form)?

---
Tom Tempelaere

Nov 16 '05 #8
"David Sworder" <ds******@cts.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...

"TT (Tom Tempelaere)" <_N_0SPA|/\|t*******@hotmail.com|/\|APS0_N_> wrote in message > >You will get a runtime exception, stating that Invoke is called
on an
already disposed object.
bummer... That's what I was afraid of.
By the way, I would do the painting in OnPaint, and just call Ivalidate if the data arrives (which your callback signals). Invalidate triggers the
painting.


good idea.
This could lead to problems. I had this problem myself in a similar

setting.
I solved it by keeping a flag to indicate whether the form is closing.
Initialize the flag to false.Make a lock object for the closing flag. In

the
OnClosing handler, begin with this:

lock( closingLock )
{
isClosing = true;
}
// ... other closing code

[...]

Excellent advice... a couple of follow ups:

Is 'closingLock' a bool value type? I don't think I'm allowed to

obtain

No.

private readonly object closingLock = new object();
a lock on a value type (am I?). So it sounds like the two places that I'll
No I didn't think so.
want to use the lock are in the Dispose() override and in the callback...
Mmm. In dispose override? Why not in the closing handler of the form (or
control)?
but still, even with the lock, couldn't I end up with a situation where
BeginInvoke() is called successfully, the lock is released, Dispose() is
then called and the lock is released, then the runtime attempts to call the delegate passed to BeginInvoke()? In that case, if the delegate is called,
No. The callback is merely registered for execution, and can only execute if
the message loop for the form is active. When it is disposed, I don't think
that the form still has a message loop, so the delegate cannot execute (and
cannot be executing because the execution of the delegate is synchronized
with the thread of the UI component).

But if you lock from the onclosing handler, you are certain that when
BeginInvoke is executing in the callback, that the form still has a message
loop.
my callback function would simply check 'IsDisposed' and return
immediately... but I'm wondering if perhaps .NET will have "issues" with
calling a delegate on a Form that is disposed?


---
Tom Tempelaere
Nov 16 '05 #9
http://weblogs.asp.net/justin_rogers...es/126345.aspx

The full pattern and logic behind the UI thread marshalling behavior is
explained
in the above link. Might be additionally helpful to those that want the
gruesome
details of exactly how and where the marshaling control is retreived from.
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:e2****************@TK2MSFTNGP11.phx.gbl...
Tom and David,

If the form was the last one, then it will try and use the handle on
that form. As mentioned before, if it is Disposed, then an exception should
be thrown. However, when the form is an MDI child form, or when dealing
with a control, the window handle that the message is sent on is not always
the handle that is associated with the control.

Which control is dependent on the parent of the Form/Control.

The reason for this behavior is that the Form class's implementation of
Invoke/BeginInvoke is inherited from Control.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"TT (Tom Tempelaere)" <_N_0SPA|/\|t*******@hotmail.com|/\|APS0_N_> wrote in
message news:76********************@phobos.telenet-ops.be...
"David Sworder" < > wrote in message
news:ey**************@TK2MSFTNGP10.phx.gbl...
> Now, that window can be your form's window, or it can be another one.
This
> is dependent on the control that Invoke is called on. If the form is
> disposed, then another window will be used.

Another window? Which one?

David


Yeah, what if the form was the last window (e.g. main form)?

---
Tom Tempelaere


Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Ingo Schasiepen | last post by:
Hi there, i'm evaluating if c# is suited to replace a script language. Most of the elements of this language can be replaced with a c#-library, but it also has some realtime-like elements. E.g.,...
4
by: LP | last post by:
Hi, I have a method that's called from another thread through a delegate. It's checking if (InvokeRequired){} and does BeginInvoke() if true. So it will be executed on the same UI thread. here's...
5
by: User N | last post by:
I have a log class with static methods that grab and release a mutex as required. The log class is designed to be called from both GUI and thread pool threads, and dump output to a logfile and a...
6
by: Valerie Hough | last post by:
I'm not entirely sure what the difference is between these two approaches. In order to avoid reentrant code, I was using Control.BeginInvoke in my UI to cause an asynchronous activity to be done...
2
by: Samuel R. Neff | last post by:
I'm trying to find a good way to handle Control.InvokeRequired without duplicating four lines of code in every function/event. Typically what I've seen in books is this: If InvokeRequired Then...
2
by: Flack | last post by:
Hello, If I understand BeginInvoke correctly, when it is called your delegate is run on a thread pool thread. Now, if you supplied a callback delegate, that too is called on the same thread...
4
by: Bill McCormick | last post by:
Hello, A timer control (I think) runs in another thread apart from a main form. In the OnTick event, you can update some form control with no worries. I'm making an AsyncronousServer class...
1
by: Amit Dedhia | last post by:
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...
7
by: Ben Voigt [C++ MVP] | last post by:
As much as the CLR team assures us that it's ok to fire-and-forget Control.BeginInvoke, it seems it isn't. Maybe this is a bug. See for example: the comments in...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.