locked
Control.Invoke() vs. Control.BeginInvoke() RRS feed

  • Question

  • first of all,i would like to apologize for my bad grammar since English is not my native tongue.
       
    To my understanding :

    Control.Invoke(delegated_method)  // Executes on the thread wich the control was created on
    witch holds its handle ,typically  this would be the main thread of a winform application .

    Control.BeginInvoke(delegated_method // Executes asynchronously on a threadPool Thread .

    according to msdn 

    "Executes a delegate asynchronously on the thread that the control's underlying handle was created on."

    My QUESTION : 

    am i to understand that beginInvoke treats the main thread in this matter as it would the thread pool , and execute the delegated method on the main thread when it "gets a chance" ?

    another question witch is raised , 
    is it possible to create a control not on the main thread ?
    if so could some one give me an example 
    Friday, February 18, 2011 6:39 AM

Answers

  • You are dealing with multiple issues at once, not just the one type, Control.  You are confronting delegates, threading, threadpool, and APM, the Asynchronous Programming Model, windows handles, the SynchronizationContext type, the AsynchOperation type, and probably a few more.  Let's try to weed through the remarks you found in the MSDN Library.   I can see that they are misleading you because you are not familiar with all of the players on the field.

    Let's start with delegates.  A delegate is a type that wraps a function pointer to a method.  You cannot define your own delegate classes.  Instead the .NET Compilers generate the classes for you through the use of the keyword, 'delegate'.  The compiler will create 3 special methods for you, depending upon how you declare the delegate signature.  These methods are named Invoke, BeginInvoke, and EndInvoke.  Please note the yellow box at this linsk.

    http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx

    http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

    The remarks you have read may seem to state the same thing.  "..executes on the thread that owns the handle..."  Obviously, they should not say the same the thing and the don't.  To understand what they mean you need to understand the APM.  Here's a link that introduces it.

    Asynchronous Programming Overview 

    That article is overwhelming for most people who are new to the concepts.  I summarized the APM in layman's terms in a recent thread.  This thread has a layman's explanation of the APM, Asynchronous Programming Model.  The guy on the horse.  It also includes an explanation of the code sample by the OP and a more technical explanation of APM, but not as in depth as the above article.

    http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/faa5da25-f50c-4a87-b1e8-ed7a6ec8cd71

    The above link also explains what I will call the "InvokeRequired Pattern", which is used to update the UI from another thread.

    The remarks associated with Control.Invoke mean that the method call is made immediately, just as if your line code called it directly.  This method will immediately execute on the thread that owns the handle.  If the CLR needs to switch threads in order to perform the operation then that is what will occur.  Thread switching can be achieved under the hood through the use of an instance of AsynchOperation instead, if you desired.

    The remarks associated with Control.BeginInvoke mean that the method is invoke by a delegate that runs on a different thread from the one where the BeginInvoke call is made.  It means a thread is obtained from the thread pool to invoke the delegate's InvocationList of targeted methods.  It does not mean the obtained thread is the thread that owns the handle associated with the Control.  It means the thread that will be used owns the SynchronizationContext of the thread associated with the handle of the object/control that is used to call BeginInvoke.

    The phrase 'on the thread that owns the handle' is referring more to the SynchronizationContext of the threads, not so much which thread will actually run the code.  Windows handles are assigned to any object that consumes unmanaged resources.  In the case of Forms and Controls, the consumed resource is video memory.

    There also something special about UI threads, their ApartmentState property.  In order to process events, threads need an assist from the OS.  The OS has what is known as a message pump, which is at the core of the multi-tasking behavior of Windows.  Messages contain information such as button clicks, key presses, and other system actions.  The OS routes messages to processes, which run threads.  These messages become your events in .NET.

    Most threads that you create do not have access to a message pump, which means controls that you create on threads have no way of interacting with the OS or Windows in your application.  Messages are routed to your applciation through the use of handles.  This means your controls need to be associated with the same handle as their host form/window. 

    I hope this clears some things up.  On that note, I will politely decline from providing a sample of how to create a control on a thread to be used on another thread.  In fact, your code must reference objects with handles only on the thread that owns the handle.

    Rudy   =8^D

     

     


    Mark the best replies as answers. "Fooling computers since 1971."

    http://rudedog2.spaces.live.com/default.aspx

    • Marked as answer by Cookie Luo Saturday, February 26, 2011 4:29 PM
    Friday, February 18, 2011 5:32 PM

All replies

  • first of all,i would like to apologize for my bad grammar since English is not my native tongue.
       
    To my understanding :

    Control.Invoke(delegated_method)  // Executes on the thread wich the control was created on
    witch holds its handle ,typically  this would be the main thread of a winform application .

    Control.BeginInvoke(delegated_method // Executes asynchronously on a threadPool Thread .

    according to msdn 

    "Executes a delegate asynchronously on the thread that the control's underlying handle was created on."

    My QUESTION : 

    am i to understand that beginInvoke treats the main thread in this matter as it would the thread pool , and execute the delegated method on the main thread when it "gets a chance" ?

    another question witch is raised , 
    is it possible to create a control not on the main thread ?
    if so could some one give me an example 
    • Merged by Rudedog2 Friday, February 18, 2011 5:46 PM : Duplicate Post :
    Friday, February 18, 2011 6:39 AM
  • They both execute on the thread on which the control was created. Invoke is synchronous and BeginInvoke is asynchronous. That's it, that's the difference.
    Friday, February 18, 2011 6:52 AM
  • Hello eranotz65,

    A control with no visual appearance can be created on other threads, but I'm afraid that the UI is handled by the main thread.


    Cornel Croitoriu - Senior Software Developer - www.Biz-Forward.com | www.Croitoriu.NET
    Friday, February 18, 2011 8:04 AM
  • Hello,

    You can create the controls on whatever thread you want, but it's the main form that handles all the messaging flow so if you won't add the controls to the collection nothing will be displayed so in one way or another you will eventually have to associate these controls with the main form, you don't really benefit anything from it, the opposite it makes things much more complicated and you risk yourself of getting undesired behaviours.

    If you mean that Control.BeginInvoke executes delegates on the main thread then you're right, it executes it asynchronously, additional benefit is that you don't need to call EndInvoke.


    Eyal, Regards.

    Any fool can write code that a computer can understand. Good programmers write code that humans can understand. -- Martin Fowler.

    SharpHighlighter - is an extension for Visual Studio, a fairly simple code highlighter for C#.
    Friday, February 18, 2011 10:09 AM
  • another question witch is raised , 
    is it possible to create a control not on the main thread ?
    if so could some one give me an example 

    You can create a Form, and all its controls on another thread. SetApartmentState(ApartmentState.STA) must be called on the thread (the equivalent of putting [STAThread] on the Main method.

    Unless you have a good reason to do that, don't.

    Friday, February 18, 2011 4:56 PM
  • You are dealing with multiple issues at once, not just the one type, Control.  You are confronting delegates, threading, threadpool, and APM, the Asynchronous Programming Model, windows handles, the SynchronizationContext type, the AsynchOperation type, and probably a few more.  Let's try to weed through the remarks you found in the MSDN Library.   I can see that they are misleading you because you are not familiar with all of the players on the field.

    Let's start with delegates.  A delegate is a type that wraps a function pointer to a method.  You cannot define your own delegate classes.  Instead the .NET Compilers generate the classes for you through the use of the keyword, 'delegate'.  The compiler will create 3 special methods for you, depending upon how you declare the delegate signature.  These methods are named Invoke, BeginInvoke, and EndInvoke.  Please note the yellow box at this linsk.

    http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx

    http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

    The remarks you have read may seem to state the same thing.  "..executes on the thread that owns the handle..."  Obviously, they should not say the same the thing and the don't.  To understand what they mean you need to understand the APM.  Here's a link that introduces it.

    Asynchronous Programming Overview 

    That article is overwhelming for most people who are new to the concepts.  I summarized the APM in layman's terms in a recent thread.  This thread has a layman's explanation of the APM, Asynchronous Programming Model.  The guy on the horse.  It also includes an explanation of the code sample by the OP and a more technical explanation of APM, but not as in depth as the above article.

    http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/faa5da25-f50c-4a87-b1e8-ed7a6ec8cd71

    The above link also explains what I will call the "InvokeRequired Pattern", which is used to update the UI from another thread.

    The remarks associated with Control.Invoke mean that the method call is made immediately, just as if your line code called it directly.  This method will immediately execute on the thread that owns the handle.  If the CLR needs to switch threads in order to perform the operation then that is what will occur.  Thread switching can be achieved under the hood through the use of an instance of AsynchOperation instead, if you desired.

    The remarks associated with Control.BeginInvoke mean that the method is invoke by a delegate that runs on a different thread from the one where the BeginInvoke call is made.  It means a thread is obtained from the thread pool to invoke the delegate's InvocationList of targeted methods.  It does not mean the obtained thread is the thread that owns the handle associated with the Control.  It means the thread that will be used owns the SynchronizationContext of the thread associated with the handle of the object/control that is used to call BeginInvoke.

    The phrase 'on the thread that owns the handle' is referring more to the SynchronizationContext of the threads, not so much which thread will actually run the code.  Windows handles are assigned to any object that consumes unmanaged resources.  In the case of Forms and Controls, the consumed resource is video memory.

    There also something special about UI threads, their ApartmentState property.  In order to process events, threads need an assist from the OS.  The OS has what is known as a message pump, which is at the core of the multi-tasking behavior of Windows.  Messages contain information such as button clicks, key presses, and other system actions.  The OS routes messages to processes, which run threads.  These messages become your events in .NET.

    Most threads that you create do not have access to a message pump, which means controls that you create on threads have no way of interacting with the OS or Windows in your application.  Messages are routed to your applciation through the use of handles.  This means your controls need to be associated with the same handle as their host form/window. 

    I hope this clears some things up.  On that note, I will politely decline from providing a sample of how to create a control on a thread to be used on another thread.  In fact, your code must reference objects with handles only on the thread that owns the handle.

    Rudy   =8^D

     

     


    Mark the best replies as answers. "Fooling computers since 1971."

    http://rudedog2.spaces.live.com/default.aspx

    • Marked as answer by Cookie Luo Saturday, February 26, 2011 4:29 PM
    Friday, February 18, 2011 5:32 PM