i am developing an application but i am unable to change the text of label quickly
i am using following code

for(int i=0;i<199;i++)
label1.text=Convert.ToString(i);

Recommended Answers

All 15 Replies

Instead of Convert.ToString(i) you could use i.ToString()

For the new text to show on your label you may need to invalidate the label and will need to give the ui time to refresh.

i try this code but both these codes hang up the form and don't shows the changing label

Can you give me some source code from which i can learn how to change the label and give ui time
Thanks on your kind reply

Well that is the correct rusult you will hang the label like that
try adding a timer with a one second delay instead of using a for loop.

The problem is that i have to change 10 values with in one second not one value.so i am unable to use time.And its becoming great challenge for me.

This works, but it lock the UI thread.

for (int i = 0; i < 200; i++)
{
    label1.Text = i.ToString();
    label1.Refresh();
    System.Threading.Thread.Sleep(10);
}

Using a System.Windows.Form.Timer gets arround that.

int i = 0;
private void timer1_Tick(object sender, EventArgs e)
{
    label1.Text = i.ToString();
    label1.Refresh();
    if (i++ > 199)
        timer1.Stop();
}

private void button1_Click(object sender, EventArgs e)
{
    i = 0;
    timer1.Interval = 10;
    timer1.Start();
}

can another way through which UI thread remain running

Run in a separate thread and update the ui thread. using background worker

Yes. You have to yield CPU time to UI thread in order to keep its message pump working:

for (int i = 0; i < 200; i++)
{
    label1.Text = i.ToString();
    label1.Refresh();
    Application.DoEvents();
    System.Threading.Thread.Sleep(10);
}

i try it but it's not working UI is also unable to move

Thanks on your kind reply

Here's a way to do it with multithreading:

public partial class Form1 : Form
    {
        Thread Updater;

        public Form1()
        {
            InitializeComponent();
        }

        public void threadMain()
        {
            for (int i = 0; i < 200; i++)
            {
                this.UpdateLabel(i.ToString());
                System.Threading.Thread.Sleep(10);
            }
        }

        // Make a thread-safe update
        public delegate void SetUpdateLabelCallback(string text);

        public void UpdateLabel(string text)
        {
            if (this.label1.InvokeRequired)
            {
                SetUpdateLabelCallback upd = new SetUpdateLabelCallback(UpdateLabel);
                this.Invoke(upd, new object[] { text });
            }
            else
            {
                label1.Text = text;
                label1.Refresh();
            }
            Application.DoEvents();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Updater = new Thread(new ThreadStart(threadMain));
            Updater.Start();
        }

    }

Now you have two threads (UI and for-loop) running at the same time so this should be as responsive as it can be.

commented: Good Helper For losers +1

can another way through which UI thread remain running

You will never, ever, see a form respond to a form change while the form's thread is active. The form thread MUST be idle, for changes to be returned to the form's thread to act on them. The timer solution works because it is a delegate running independently of your form thread. (There is a bug in the given logic "if (++i > 199)" will stop at 199 just like your loop.) If you want the user to be unable to do anything until the count is finished, then use his first solution. If you want another way, this will work, but I bet you like it less than the timer solution.

1. Create a routine to handle updating of your label from the passed information.
2. Create a small class that has a delegate routine. A looping routine.
3. Assign your form routine to your delegate.
4. start the looping routine in a new thread.
5. In the loop call the delegate and then Sleep. Forget the Refresh, you don't need it.

PS. I have a combo box that picks between 10, 5, 1, 0.1, 0.5, 0.05, 0.01, and 0.0 convert that to an integer a 1000 times bigger and sleeps for that time. (I sleep for a maximum of 500 and increment up to the set time when it is bigger than that. When you sleep for 10 seconds, it is agonizing to wait for it to finish and this appears to be an instant response.) I pass the value to an int property in my looping class and it is thread safe because the property handles the actual int value and after instantiating it is never changed, just read by the class.

PPS The resolving of the form is so slow, I can't tell any difference in speed between 0 and 0.01. It is slightly noticable at 0.05, but it's so fast I still can't read it in that time. Other than the novelty factor of watching the flashing text, I prefer reading my solutions from an ArrayList and looking at the results in my time.

I use the background worker tool to run things on separate threads. here's a quick example there might be a better way.. but I found this is the easiest.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 10000; i++)
            {
                backgroundWorker1.ReportProgress(i, i);
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text = "Record " +  e.UserState.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.