3

I know that this question had been asked 100 times before, but all the answers I read didn't worked for me. So, I'll try my luck and ask again.

I have a SliderBar that calls a method on the ValueChanged event. In this method I do some stuff that takes time, and I want that in this time the user will see an "working" ProgressBar (IsIndeterminate=true).

Unfortunately, I don't succeed to make the ProgressBar start working (in the UI) until all the method loops finished. I tried threads, BackgroundWorker and async Tasks but with no success..

What am I doing wrong?

This is the method:

    private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e){
        WorkingBar.IsIndeterminate = true;      //change the progressBar          
        SqlAThread = new Thread(SqlAStart);     
        SqlAThread.Start();
    }

The thread:

    private void SqlAStart()
    {
        ... //do some stuff
    }
Kristof U.
  • 1,263
  • 10
  • 17
Yaron
  • 233
  • 1
  • 14
  • The dispatcher syntax in your doWork method is what you want to use, you want to put your UI code in there to push the actions you want to do onto the UI thread, at the moment all you seem to be doing here is changing a property of the progress bar, use this syntax to update the progress bar also. – JMK Nov 15 '13 at 15:59
  • @JMK this proparty is what I want to change, when this proprty is "true" the progressBar shold be in "working" mode (I think...?). actually, it works, but only when all of the loop done.. =/ – Yaron Nov 15 '13 at 16:13

3 Answers3

4

In Slider_ValueChanged you start a new tread to run the time-consuming SqlAStart() method, but SqlAStart immediately pushes the work back to the UI thread (via Dispatcher.Invoke()). Therefore, your UI hangs and you don't see any ProgressBar progress until the work is done.

In SqlAStart, only do a Dispatcher.Invoke() where you need to update the progress bar:

private void SqlAStart()
{
    ServerThread = new Thread(HttpSrv.listen);
    ServerThread.Start();
    ...

    this.Dispatcher.Invoke((Action)(() => {
        WorkingBar.Value = ...                
    }));

    ....
}
Sphinxxx
  • 12,484
  • 4
  • 54
  • 84
1

This is quite easy using IProgress<T>:

private async void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
  if (State.Value > 0)
  {
    var progress = new Progress<int?>(value =>
    {
      WorkingBar.IsIndeterminate = (value == null);
      if (value != null)
        WorkingBar.Value = value.Value;
    });
    await Task.Run(() => doWork(progress));
    Task.Run(SqlAStart);
  }
  ...
}

private void SqlAStart(IProgress<int?> progress)
{
  ServerTask = Task.Run(HttpSrv.listen);
  ...
}

private void doWork(IProgress<int?> progress)
{
  if (progress != null)
    progress.Report(null);
  ...
}

Note that you should (almost) never use Dispatcher, Thread, or BackgroundWorker in modern applications.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Hi @Stephen Cleary, I tried your code (btw, thanks, I dosnt knew IProgress before) but still, the UI update just after SqlAstart finish.. – Yaron Nov 15 '13 at 17:25
  • @Yaron What is the method doing? If it's invoking to the UI thread and blocking it for a while, then obviously nothing else can update while it's in progress. – Servy Nov 15 '13 at 17:28
0

Rather than type out the whole lengthy process, I'd invite you to take a look at my answer to the Progress Bar update from Background worker stalling question here on StackOverflow. It demonstrates how to correctly use a BackgroundWorker object to update the progress value of a ProgressBar.

You may also like to view the BackgroundWorker Class page on MSDN for more detailed information.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Hi @sheridan I tried your code (actually it was my first try) I understand your example but don't sucseed to use it in my code.. – Yaron Nov 15 '13 at 16:24
  • @Yaron, ignore your code for now. Put that example code into a new WPF application or project and get it working. *Then* with a working example to experiment with, you *should* be able to apply it to your code. – Sheridan Nov 15 '13 at 16:27
  • I tried and it worked in the new project. but now when i try to do it in my code it dosnt work for me – Yaron Nov 15 '13 at 17:28