ali kiani
ali kiani

Reputation: 887

UI Not Updating when Using Thread.Sleep

I have application that have button i want when click this button every 1 second add special text add to a TextBox but when click this button all time wait and enter all text together.

what is problem ?

for example :

 private void button2_Click(object sender, RoutedEventArgs e)
        {
            Random rand = new Random(DateTime.Now.Millisecond);
            textBox1.Text = "";
            for (int i = 0; i < 10; i++)
            {
                textBox1.Text += rand.Next(1,10) + "\n";
                System.Threading.Thread.Sleep(1000);
            }
        }

thanks.

Upvotes: 0

Views: 2847

Answers (5)

Dmitry
Dmitry

Reputation: 26

The best way to achieve this is to use a BackgroundWorker in combination with INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

and implement property

    private string _value;
    public string Value
    {
        get { return _value; }
        set
        {
            if(value.Equals(_value)) return;
            _value = value;
            NotifyPropertyChanged("Value");
        }
    }

Call the method

    private void Foo()
    {
        var rand = new Random(DateTime.Now.Millisecond);

        for (var i = 0; i < 50; i++)
        {
            Value += rand.Next(1, 10) + "\n";
            System.Threading.Thread.Sleep(500);
        }
    }

in the event DoWork BackgroundWorker like this

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerAsync();
    }


    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        Foo();
    }

Upvotes: 0

Afnan Bashir
Afnan Bashir

Reputation: 7429

Making thread sleep will make your main thread to sleep.

following may work

make a function

private void wait(int ms)
{
   for(int x=0;x<ms;x++)
   {
      Thread.Sleep(1);
      System.Windows.Forms.Application.DoEvents();
   }
}

This will do events after each MiliSecond

and you can use it

private void button2_Click(object sender, RoutedEventArgs e)
        {
            Random rand = new Random(DateTime.Now.Millisecond);
            textBox1.Text = "";
            for (int i = 0; i < 10; i++)
            {
                textBox1.Text += rand.Next(1,10) + "\n";
                wait(1000);
            }
        }

Upvotes: 0

Tim M.
Tim M.

Reputation: 54387

@Slaks is correct; you are sleeping the UI thread.

I would suggest a timer as a more elegant solution. Note that events (such as from a background worker or a timer) that are raised in another thread will need to be marshalled back to the UI thread for the form.

Upvotes: 1

Saeb Amini
Saeb Amini

Reputation: 24439

The text is actually being added to your textbox in 1 second intervals, you just don't see it until the loop is over because you have put the GUI's thread to sleep and it's unable to update itself.

Upvotes: 1

SLaks
SLaks

Reputation: 887877

You're sleeping on the UI thread.
This freezes the UI.

Instead, use a BackgroundWorker and its progress events.

Upvotes: 6

Related Questions