Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
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 17-Feb-11 20:32pm
otzap456

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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
  Permalink  
Comments
JF2015 at 18-Feb-11 2:41am
   
Very detailed answer and a good read too. 5+
SAKryukov at 18-Feb-11 3:01am
   
Thank you.
--SA
Tarun.K.S at 18-Feb-11 3:27am
   
Perfect answer! Bookmarked too!
otzap at 18-Feb-11 3:30am
   
thanks , u made that clear
i wasn't aware of the Dispatcher
SAKryukov at 18-Feb-11 3:32am
   
You're very welcome.
Dispatcher is important to know, yes...
--SA
Abhinav S at 18-Feb-11 3:32am
   
Awesome answer. A 5 was too less.
SAKryukov at 18-Feb-11 3:33am
   
Enough...:-) Thank you very much, Abhinav.
Very repeating set of question can be covered, hope we can reuse it.
--SA
Espen Harlinn at 16-Mar-11 16:58pm
   
A 5 here, and ...
SAKryukov at 16-Mar-11 17:15pm
   
Thank you, and..?
--SA
Espen Harlinn at 16-Mar-11 17:18pm
   
... and a 5 here - you made a link to this answer today :)
SAKryukov at 16-Mar-11 18:06pm
   
Thank you, Espen, I just saw it...
--SA
Mark Salsbery at 23-Jul-11 19:08pm
   
A couple comments...
 
>>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
 
Not true for BeginInvoke(). The delegate is still queued, which can be useful to queue a work item on the same thread but after any current queued items have completed.
 
>>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!
 
Sure about that? The work item should be queued on the thread that created the dispatcher...
SAKryukov at 1-Dec-11 23:08pm
   
Frankly, I did not know that BeginInvoke still uses the queue even if called in the same UI thread. This is good to know even though I don't allow this to happen. I can understand it, but do you have a link?
 
When I said that invocation mechanism does not work without a UI thread, I actually meant exactly what you say; sorry if I did not make it clear.
 
So, thank you very much for these precise comments (I would like to see some reference of the 1st one)!
--SA

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

  Print Answers RSS
0 Dnyaneshwar@Pune 719
1 TheRealSteveJudge 240
2 CHill60 240
3 CPallini 235
4 Peter Leow 200
0 Sergey Alexandrovich Kryukov 9,078
1 OriginalGriff 6,771
2 Peter Leow 4,282
3 Zoltán Zörgő 3,809
4 Richard MacCutchan 2,661


Advertise | Privacy | Mobile
Web04 | 2.8.150128.1 | Last Updated 18 Feb 2011
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100