views:

565

answers:

7

I want to update a progress bar from running 1 to 100 with this code.

for (int i = 0; i <= 100; i++) {
    System.Threading.Thread.Sleep(100);
    progressBar1.Value = i;
}

But the result is, the UI freeze until looping finish.

I know Dispatcher can help, but I don't want to split function.

Is there any command to update UI immediately like..

for (int i = 0; i <= 100; i++) {
    System.Threading.Thread.Sleep(100);
    progressBar1.Value = i;
    UpdateUINow();
}

Edit: I'm using WPF, and I use Thread.Sleep to simulate long running process.

In fact, I want any command liked Application.DoEvents. But I cannot find this command in WPF.

A: 

See if DoEvents can help you out here.

luvieere
A: 
Application.DoEvents()

should do the trick

Grizzly
+14  A: 

Please don't sleep in the UI thread. It will freeze your UI - it's a bad thing to do.

Either have a timer of some kind (use the right kind of timer and you should be able to get it to fire in your UI thread) or use a separate thread (either via BackgroundWorker, a new separate thread, or the ThreadPool) and make it call back to the UI thread to update it.

Application.DoEvents is a hacky workaround in WinForms, but the fact that you've mentioned a Dispatcher suggests you're using WPF - is that the case? The kind of timer you should use (if you want to use that solution) will depend on the UI framework you're using.

Jon Skeet
`Invoke(delegateInstance)` will do the job in WinForms.
Mehrdad Afshari
+1 So glad someone was able to counter the ever-growing list of `DoEvents` recommendations while I ate my chicken fingers.
Adam Robinson
+2  A: 

Another alternative is to use a BackgroundWorker (a ThreadPool would be a bit overkill here but it technically could be used) and have it report progress.

Stephen Wrighton
+2  A: 

I would use a C# BackgroundWorker to update your UI. This isn't working like you'd expect it to because the Thread.Sleep() is freezing your UI thread.

EDIT: Tutorial that does a bit more what you want here

Scott Anderson
+1  A: 

Ditto on sleeping in the main (GUI) thread -- avoid it at all costs. Although you don't want to Dispatcher, I'd still recommend trying (something like) this:

public partial class Window1 : Window
{
    DispatcherTimer _timer = new DispatcherTimer();

    public Window1()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        progressBar1.Value = 0;
        progressBar1.Maximum = 100;
        _timer.Interval = TimeSpan.FromMilliseconds( 100);
        _timer.Tick += ProgressUpdateThread;
        _timer.Start();
    }

    private void ProgressUpdateThread( object sender, EventArgs e)
    {
        progressBar1.Value++;
    }
}
Dave
A: 

While I agree with the basic ideas - don't sleep the UI thread for obvious reasons - there nothing wrond with using a DoEvents analog as long as you can ensure that it isn't going to get called again to create a nested set of event handlers all active - but even here it isn't necessarily wrong. I found the discussion in Loading Bitmaps: DoEvents and the closure pattern to be helpful without being too prescriptive - i.e. it doesn't simply say DONT DO IT!"