Wannabe
Wannabe

Reputation: 596

Busy indicator does not show until data shows

I have a control in my project that provides a busy indicator (rotating circle). I'd like it to run when a user selects a file to load data into a data grid. The busy indicator does not show up until my data grid is populated though. How can I get my busy indicator to show while the data is being retrieved? I believe I'm supposed to use a thread, but am not too knowledgeable with them yet and am trying to learn. I've tried many different ways and below is my latest attempt, which I do not know if I am anywhere close.

public void DoWork()
{
this.StartProgressBar();

Task.Factory.StartNew(() =>
    {
        UIDispatcher.Current.BeginInvoke(() =>
            {
                if (fileCompleted != null && !string.IsNullOrEmpty(fileCompleted.SelectedFile))
                {
                    this.TestResults.Clear();

                    LoadedFileInfo info = this.Model.OpenTestCompleted(fileCompleted.SelectedFile);

                    foreach (var model in info.Sequence.Models)
                    {
                        foreach (var details in model.Tests)
                        {
                            this.TestResults.Add(new TestResultsModel(details, model.Name.Substring(0, model.Name.IndexOf('.'))));
                        }
                    }
                }
            });
    });
}

private void StartProgressBar()
{
    TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();

    CancellationToken cancelationToken = new CancellationToken();
    Task.Factory.StartNew(() => this.StopProgressBar()).ContinueWith(
        m => 
        {
            this.ToggleProgressBar = true;
        },
        cancelationToken,
        TaskContinuationOptions.None, 
        scheduler);
}

private void StopProgressBar()
{
    this.ToggleProgressBar = false;
}

Upvotes: 0

Views: 356

Answers (1)

denis morozov
denis morozov

Reputation: 6316

I really agree with @Ben, you should research how to use Tasks. You are creating background threads, and doing work on the UI thread in them anyway, which inevitably hold the UI thread. Try something simpler and see if it works. As far as your cancellation token goes, I don't see how and were you'd be able to reset it, as it is not a property in your class, so here's a sample without it..

How about something like this:

public void DoWork()
{
   //done on the UI thread
   this.ToggleProgressBar = true;

  //done on the background thread, releasing UI, hence should show the progress bar
  Task.Factory.StartNew(() =>
  {
      if (fileCompleted != null && !string.IsNullOrEmpty(fileCompleted.SelectedFile))
      {
          this.TestResults.Clear();
          LoadedFileInfo info = this.Model.OpenTestCompleted(fileCompleted.SelectedFile);

          foreach (var model in info.Sequence.Models)              
              foreach (var details in model.Tests)                  
                   this.TestResults.Add(new TestResultsModel(details, model.Name.Substring(0, model.Name.IndexOf('.'))));
       }
      //after all that (assumingly heavy work is done on the background thread,
      //use UI thread to notify UI
      UIDispatcher.Current.BeginInvoke(() =>
          {
             this.ToggleProgresBar = false;
          }
});

}

Upvotes: 3

Related Questions