943,659 Members | Top Members by Rank

Ad:
  • C# Discussion Thread
  • Marked Solved
  • Views: 16677
  • C# RSS
Mar 21st, 2009
0

Update label text from another thread

Expand Post »
I'm imitating progressbar value change like:
C# Syntax (Toggle Plain Text)
  1. private void playAnimation()
  2. {
  3. for(int i=1;i<=100;i++)
  4. {
  5. this.progressBar1.Value = i;
  6. System.Threading.Thread.Sleep(20);
  7. percent = i;
  8. }
  9. }
At the same time I try to run another thread, to update label text like "...% completed". Of course I couldn't change text of label that was created in main thread ( I know it's possible using delegates or something like that..), so I created label in the new thread.
C# Syntax (Toggle Plain Text)
  1. private static void percentage()
  2. {
  3. Label threadLabel = new Label();
  4. Point p = new Point(418,290);
  5. threadLabel.Location = p;
  6. threadLabel.Show();
  7. for (int i = 0; i < 100; i++)
  8. threadLabel.Text = i.ToString()+" % completed";
  9. }
  10. static ThreadStart ts = new ThreadStart(percentage);
  11. Thread oThread = new Thread(ts);
  12. .....
  13. oThread.Start();
  14. playAnimation();
  15. oThread.Abort();
However the label doesn't show up, but I can see the text property changes when using debugging or Messageboxes..
Can anybody give me a clue where is the problem? Or at least the correct way to access main form labels from another thread..
Similar Threads
Reputation Points: 10
Solved Threads: 0
Light Poster
Wiizl is offline Offline
25 posts
since Jan 2007
Mar 22nd, 2009
0

Re: Update label text from another thread

I sugest you take a different tact.

What I typically do for managing thread messages is I create a simple EventArgs class to hold the message information, a Delegate to represent the main thread method that will use the information, and an eventhandler in the main thread that can be assigned to an event in the thread.

So to start, build a simple EventArgs class
C# Syntax (Toggle Plain Text)
  1. public class ProgressEventArgs : EventArgs
  2. {
  3. private int _maxValue = 100;
  4. private int _value = 0;
  5. private string _text = string.Empty;
  6.  
  7. public int MaxValue
  8. {
  9. get { return _maxValue; }
  10. }
  11. public int Value
  12. {
  13. get { return _value; }
  14. }
  15. public string Text
  16. {
  17. get { return _text; }
  18. }
  19. public ProgressEventArgs(string text, int value, int maxValue)
  20. {
  21. _text = text;
  22. _value = value;
  23. _maxValue = maxValue;
  24. }
  25. public override string ToString()
  26. {
  27. return _text;
  28. }
  29. }

Now create a public delegate. Typically I have a constants.cs file where I create all of my constants, and then outside of the constants class, but in the same name space, I create my delegates like this:

C# Syntax (Toggle Plain Text)
  1. namespace MyNameSpace
  2. {
  3. public delegate void ProgressEvent(object sender, ProgressEventArgs e);
  4. public class Constants
  5. {
  6. }
  7. }

OR you can just add the delegate to the main form.

Next you want to create the method that will receive the event, and process the information (in the main form)
C# Syntax (Toggle Plain Text)
  1.  
  2. public void SetProgressEvent(object sender, ProgressEventArgs e)
  3. {
  4. if( label1.InvokeRequired )
  5. {
  6. ProgressEvent d = new ProgressEvent(SetProgressEvent);
  7. this.Invoke(d, new object[] { sender, e });
  8. }
  9. else
  10. {
  11. progressBar1.Maximum = e.MaxValue;
  12. progressBar1.Value = e.Value;
  13. label1.Text = e.Text;
  14. }
  15. }

Okay, now you want to assign the event to this method. You can do this in the main constructor of your form if this is also where your thread is living. If the thread is in a sperate file or class, then you will declare the event in that class, and attach it from the main form.
C# Syntax (Toggle Plain Text)
  1. onProgressEvent +=new ProgressEvent(SetProgressEvent);

Now inside the thread, you can check to see if the event handler is assigned, and if so send the data to it.
C# Syntax (Toggle Plain Text)
  1. // INSIDE THE THREAD
  2. if(onProgressEvent != null)
  3. {
  4. for(int i=1;i<=100;i++)
  5. {
  6. onProgressEvent(this, new ProgressEventArgs(
  7. i.ToString()+" % completed"
  8. , i
  9. , 100));
  10. System.Threading.Thread.Sleep(20);
  11. }
  12. }

The key to inter thread communication when a Component is involved (or any non thread safe object) is to perform the Invoke as you can see in the SetProgressEvent method.

Hope this help,
// Jerry
Reputation Points: 69
Solved Threads: 75
Posting Pro in Training
JerryShaw is offline Offline
465 posts
since Nov 2006
Mar 22nd, 2009
0

Re: Update label text from another thread

wow thanks for such detailed information!
just to clear things up- that last part should be inside the void method that is passed to threadStart and later to thread, right?
Reputation Points: 10
Solved Threads: 0
Light Poster
Wiizl is offline Offline
25 posts
since Jan 2007
Mar 22nd, 2009
1

Re: Update label text from another thread

Yes, the for--loop is inside the thread method.
Reputation Points: 69
Solved Threads: 75
Posting Pro in Training
JerryShaw is offline Offline
465 posts
since Nov 2006
Apr 23rd, 2011
0
Re: Update label text from another thread
Can you guide me to use the same method, but not in windows form? just to update the label text. Thanks.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
aishev is offline Offline
2 posts
since Apr 2011
Apr 23rd, 2011
0
Re: Update label text from another thread
This is another version of updating Label`s text over the thread:

C# Syntax (Toggle Plain Text)
  1. delegate void LabelDelegate(string message);
  2. public Form1()
  3. {
  4. InitializeComponent();
  5. }
  6.  
  7. private void UpdatingLabel(string msg)
  8. {
  9. if (this.label1.InvokeRequired)
  10. this.label1.Invoke(new LabelDelegate(UpdatingLabel), new object[] { msg });
  11. else
  12. this.label1.Text = msg;
  13. }

Its faster and easier...
Reputation Points: 537
Solved Threads: 398
Postaholic
Mitja Bonca is offline Offline
2,010 posts
since May 2009
Apr 23rd, 2011
-1
Re: Update label text from another thread
Click to Expand / Collapse  Quote originally posted by Wiizl ...
I'm imitating progressbar value change like:
C# Syntax (Toggle Plain Text)
  1. private void playAnimation()
  2. {
  3. for(int i=1;i<=100;i++)
  4. {
  5. this.progressBar1.Value = i;
  6. System.Threading.Thread.Sleep(20);
  7. percent = i;
  8. }
  9. }
At the same time I try to run another thread, to update label text like "...% completed". Of course I couldn't change text of label that was created in main thread ( I know it's possible using delegates or something like that..), so I created label in the new thread.
C# Syntax (Toggle Plain Text)
  1. private static void percentage()
  2. {
  3. Label threadLabel = new Label();
  4. Point p = new Point(418,290);
  5. threadLabel.Location = p;
  6. threadLabel.Show();
  7. for (int i = 0; i < 100; i++)
  8. threadLabel.Text = i.ToString()+" % completed";
  9. }
  10. static ThreadStart ts = new ThreadStart(percentage);
  11. Thread oThread = new Thread(ts);
  12. .....
  13. oThread.Start();
  14. playAnimation();
  15. oThread.Abort();
However the label doesn't show up, but I can see the text property changes when using debugging or Messageboxes..
Can anybody give me a clue where is the problem? Or at least the correct way to access main form labels from another thread..
hi

what is the problem you are facing in this threading ? please write your error while threading generate
Reputation Points: 0
Solved Threads: 3
Junior Poster in Training
crishjeny is offline Offline
98 posts
since Nov 2010
Apr 23rd, 2011
0
Re: Update label text from another thread
I want too update label.text, but in aspx webforom, not in windows form. Can anyone get any suggestions?thanks.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
aishev is offline Offline
2 posts
since Apr 2011
Apr 23rd, 2011
0
Re: Update label text from another thread
This is another version of updating Label`s text over the thread:

C# Syntax (Toggle Plain Text)
  1. delegate void LabelDelegate(string message);
  2. public Form1()
  3. {
  4. InitializeComponent();
  5. }
  6.  
  7. private void UpdatingLabel(string msg)
  8. {
  9. if (this.label1.InvokeRequired)
  10. this.label1.Invoke(new LabelDelegate(UpdatingLabel), new object[] { msg });
  11. else
  12. this.label1.Text = msg;
  13. }

Its faster and easier...
Mitja, inline delegate assignment is not any faster in execution. As for easier, only saves the typing of a delegate type and a variable name. As for maintenance and readability, I prefer the longer form especially is using non standard EventArg handlers.
JMO
Reputation Points: 69
Solved Threads: 75
Posting Pro in Training
JerryShaw is offline Offline
465 posts
since Nov 2006
Jul 28th, 2011
0

Update Control property from another thread

private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(Go);
th.Start(textBox1.Text);
}

private void Go(object obj)
{
button1.Invoke(new Action(() => button1.Text = obj as string));
}
Reputation Points: 10
Solved Threads: 0
Newbie Poster
rasoulian is offline Offline
1 posts
since Jul 2010

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C# Forum Timeline: SQL Table designer field description as column?
Next Thread in C# Forum Timeline: Loop not working





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC