469,964 Members | 1,750 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,964 developers. It's quick & easy.

Confused about using Invoke in worker threads. - C#

63
So why is it that we need to use the Invoke method when updating the GUI?

The following is the way we are suppose to update GUI components:

Expand|Select|Wrap|Line Numbers
  1. delegate void textIt(object o);
  2. public partial class Form1 : Form
  3. {
  4.         public Form1()
  5.         {
  6.             InitializeComponent();
  7.         }
  8.         private void Form1_Load(object sender, EventArgs e)
  9.         {
  10.             //Main Thread
  11.             Label l = new System.Windows.Forms.Label();
  12.             this.Controls.Add(l);
  13.  
  14.             System.Threading.Thread testThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(testStart));
  15.             testThread.Start(l);
  16.  
  17.         }
  18.         private void testStart(object o)
  19.         {
  20.             //testThread
  21.             if (((Label)o).InvokeRequired)
  22.             {
  23.                 textIt t = new textIt(testStart);
  24.                 this.Invoke(t, o);
  25.             }
  26.             else
  27.             {
  28.                 ((Label)o).Text = "TEST";
  29.             }
  30.        }
  31. }
  32.  

If I delete the delegate and change the method testStart(object o) to:

Expand|Select|Wrap|Line Numbers
  1. private void testStart(object o)
  2. {
  3.        ((Label)o).Text = "TEST";
  4. }
  5.  
I don't get any problems. In fact, I have yet to have a problem with X number of threads changing the GUI directly as long as I implement mutual exclusion correctly.

I have read that the properties cannot be changed by any thread other then the one that created it. Is that a suggestion or a fact? If it is a suggestion, then what could go wrong? If it is a fact then how is it that I have been accessing the properties directly from different threads? does the compiler rewrite the code so that it does call Invoke?
May 21 '08 #1
5 1401
iLL
63
Sorry for this but... Bump
May 21 '08 #2
Plater
7,872 Expert 4TB
It's not that they "CANNOT" it's that they "SHOULD NOT"
You will only ever see an exception when in debug mode.
What it could cause is messages coming in mixed up with each other because one thread tries to access the gui object while another one is in the middle of it.

Expand|Select|Wrap|Line Numbers
  1. private delegate void ChangeTextCallback(string msg);
  2.  
  3. private void SetLabelText(string msg)
  4. {
  5.     if (this.InvokeRequired)
  6.     {
  7.         ChangeTextCallback d = new ChangeTextCallback(SetLabelText);
  8.         this.Invoke(d, msg);
  9.     }
  10.     else
  11.     {
  12.         myLabel1.Text = msg;
  13.     }
  14. }
  15.  
May 21 '08 #3
iLL
63
I'm still a little confused

If I implement mutual exclusion properly, then do I still need to worry about implementing it this way?

And if I do use this method, do I still need to use locks? And if not, what if two different threads call Invoke at the same time, how does that work? Does some sort of stack keep track of waiting Invoke calls?
May 21 '08 #4
Plater
7,872 Expert 4TB
If I understand correctly, invoke sends out a special windows message on the message pump with the applicable data as a payload.
So if multiple threads call invoke, multiple messages will be sent out, but processed one at a time?
May 21 '08 #5
iLL
63
Thanks ;)

.................
May 21 '08 #6

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

11 posts views Thread by Doug Thews | last post: by
4 posts views Thread by Brad Coble | last post: by
1 post views Thread by rainxy | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.