Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
2.40/5 (4 votes)
See more:
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
Posted

1 solution

Nothing like that.

First of all, what you call main thread is more usually called UI thread.

Control.Invoke and Control.BeginInvoke work in any thread. The functionality is completely insensitive to the origin of the thread: it can be UI thread, a thread created through System.Threading.Thread constructor, a thread from the thread pool or a thread created by System.ComponentModel.BackgroundWorker.

The purpose of this API is to dispatch a call of the delegate instance on the UI thread. If the call to Control.Invoke or Control.BeginInvoke is done in UI thread, the delegate will be called immediately. As the invocation mechanism is redundant in this case, this can be avoided by checking the predicate property Control.InvokeRequired. If invocation mechanism is not required, regular call of control's method or property is preferred. This predicate is only needed for some generalization of some call which can be done from different threads: sometimes in UI thread, sometimes not. In many cases the developer knows for sure that the delegate will be called on from non-UI thread only; in this case Control.InvokeRequired is not needed, as invocation should be used anyway.

Now, UI libraries (both System.Windows.Forms and WPF) are designed in such a way that all calls to all UI controls and Application should never be done directly, but should dispatched to the UI thread. There is another interface to this functionality common for Forms and FPW, with highly extended functionality: System.Windows.Threading.Dispatcher, it also has Invoke and BeginInvoke methods, several overloads. The instance of Dispatcher can be obtained using the static property System.Windows.Threading.Dispatcher.CurrentDispatcher (this property either instantiates new instance or use previously created instance of Dispatcher).

Now, Dispatcher methods, Control.Invoke and Control.BeginInvoke use the same mechanism of dispatching a delegate to the UI thread: the delegate instance and instances of actual calling parameters are put to some queue, which is read by the WPF or System.Windows.Forms UI thread. In main UI cycle, this data is removed from the queue and used to make an actual call. Each thread instance has the invocation list; each element of invocation list encapsulates delegate entry point, this parameter used to access the instance of the declaring class of the method (if the method is non-static) and all instances of call parameters. All this data is used for the actual call.

Now we came to the difference between Invoke and BeginInvoke. For Invoke, return value obtained from the call is returned to caller of Invoke. It means that the thread synchronization is blocking for the calling non-UI thread.

In contrast, BeginInvoke returns immediately with the result of the type System.IAsyncResult, so this call itself in non-blocking. This invocation method should be used in most cases, especially when return result is not needed; a typical example: getting UI thread showing notification from non-UI thread status.

If return result from BeginInvoke is needed, the situation is pretty complex, as result is not ready immediately, so some kind of wait is needed anyway. It is not well documented in standard help documentation. Basically, there are three ways of obtaining the result of invocation later, one of them is calling blocking EndInvoke. You can find further details and recommendations here: http://support.microsoft.com/kb/315582[^].

There is a very popular misconception that the invocation mechanism can be used with any thread through Dispacher. This is not true. The Dispatcher really works for non-UI applications as well, but is Invoke or BeginInvoke is used, it does not do anything useful if there is no active UI thread! The call to those method is equivalent to regular call of the delegate on the same thread.

Is is possible to use the similar mechanism on any thread? No, but it can be done on specially written custom thread using a blocking queue, when the elements of the queue are delegate instances. A complete code with usage samples can be found in my Tips/Tricks article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^]. If you look at the source code, it will give you a good idea on how UI thread invocation mechanism works.

—SA
 
Share this answer
 
Comments
JF2015 18-Feb-11 2:41am    
Very detailed answer and a good read too. 5+
Sergey Alexandrovich Kryukov 18-Feb-11 3:01am    
Thank you.
--SA
Tarun.K.S 18-Feb-11 3:27am    
Perfect answer! Bookmarked too!
otzap 18-Feb-11 3:30am    
thanks , u made that clear
i wasn't aware of the Dispatcher
Sergey Alexandrovich Kryukov 18-Feb-11 3:32am    
You're very welcome.
Dispatcher is important to know, yes...
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900