Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / June 2007

Tip: Looking for answers? Try searching our database.

Question about BeginInvoke.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jason Kendall - 15 Jun 2007 18:43 GMT
I don't understand why the order of events happening here is
predictable.

Let's say I have a base class user control with a 'Load' event handler
and a sub:
  Private Sub iMatterControlForm_Load(ByVal sender As Object, ByVal e
As System.EventArgs) Handles Me.Load
       Debug.WriteLine("BASE CLASS LOAD")
       Me.BeginInvoke(New MethodInvoker(AddressOf TestOnLoad))
  End Sub

  Private Sub TestOnLoad()
       Debug.WriteLine("ON LOAD Base Class")
  End Sub

I then have a class which inherits from the base which takes a long
time to execute.

 Private Sub MatterProfile_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
           Debug.WriteLine("BEFORE SLEEP SUB Class")
           System.Threading.Thread.Sleep(5000)
           Debug.WriteLine("After Seep SUB Class")
  End Sub

Now, I am pretty sure that calling 'BeginInvoke' calls the delegate on
a ThreadPool thread.  So, to my ignorant mind, I would expect my
output window to show something like this, with a possible race
condition flip flopping the middle two statements.
BASE CLASS LOAD
BEFORE SLEEP SUB Class
ON LOAD Base Class
AfterSleep SUB Class

In fact what always happens is that I see the following:
BASE CLASS LOAD
BEFORE SLEEP SUB Class
AfterSleep SUB Class
ON LOAD Base Class

So, it looks to me like there's an execution stack (or something) that
has the base Load event and the subclass Load event already stacked up
and the ThreadPool cannot start executing the TestOnLoad method until
the other two functions are executed off of the stack.

Can one of you bright people out there explain what's happening here?
I trust my results, but I'd MUCH rather understand the 'why'.

Thanks!

Signature

Jason Kendall
jasonkendall@hotmail.com

Peter Duniho - 15 Jun 2007 19:16 GMT
> Now, I am pretty sure that calling 'BeginInvoke' calls the delegate on
> a ThreadPool thread.  [...]
[quoted text clipped - 6 lines]
> Can one of you bright people out there explain what's happening here?
> I trust my results, but I'd MUCH rather understand the 'why'.

Well, assuming that your code is actually within the Form instance, then  
the reason you're seeing what you're seeing is that you're wrong about  
your assumption "that calling 'BeginInvoke' calls the delegate on a  
ThreadPool thread".

One of the few things that really annoys me about the design of .NET is  
the use of the same word to describe two fundamentally different things.  
In this case, you're calling the Control.BeginInvoke() method, not the  
Delegate.BeginInvoke() method.  In the latter case, it would indeed  
execute on a ThreadPool thread.  However, in the former case the  
invocation is queued on the Control's message queue and always executed on  
the thread that owns that Control.

In your case, the Control is the Form, and you will never execute the  
delegate until the current handler has exited and returned control to the  
message pump.  So the BeginInvoke() called in the base class will never  
get executed until all of the Load event handlers are finished.

(Another area where the same term is used to describe two completely  
different things is "events".  A class can have an event, which allows  
delegates to be subscribed, and of course there are also events that you  
can wait on, as a synchronization mechanism)

Pete
Jason Kendall - 15 Jun 2007 22:15 GMT
Holy smokes, this is such a good explanation.

Thanks so much!

Signature

Jason Kendall
jasonkendall@hotmail.com

>> Now, I am pretty sure that calling 'BeginInvoke' calls the delegate on
>> a ThreadPool thread.  [...]
[quoted text clipped - 31 lines]
>
>Pete
Jon Skeet [C# MVP] - 15 Jun 2007 22:09 GMT
<snip>

> Now, I am pretty sure that calling 'BeginInvoke' calls the delegate on
> a ThreadPool thread.

No. The whole point of Control.Invoke/BeginInvoke is to call the
delegate on the UI thread responsible for that control.

I suspect you're getting confused with calling BeginInvoke *on* a
delegate, which does indeed use a ThreadPool thread.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.