tags:

views:

459

answers:

2

Hi, I was looking for a way to create a nice progressbar. I found some code which I used and it worked great if I used a loop. But now I wanted to use it in a real decent application and it gave me a lot of trouble. I have an application where I lookup data on IMDB, so I make a connection to IMDB for for example 500 movietitles, so this takes a while. So I wanted to show a progressbar where the bar grew for each movie it looked up and with some extra info on the movietitle.

I use the following class:

public partial class ProgressDialog : Window, IProgressContext
{
    public ProgressDialog()
    {
        InitializeComponent();
        IconBitmapDecoder ibd = new IconBitmapDecoder(
        new Uri("IMDB.ML.ico", UriKind.RelativeOrAbsolute),
        BitmapCreateOptions.None, BitmapCacheOption.Default);
        this.Icon = ibd.Frames[0];
    }
    public void UpdateProgress(double progress)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Background,
            (SendOrPostCallback)delegate { Progress.SetValue(ProgressBar.ValueProperty, progress); }, null);
    }

    public void UpdateStatus(string status)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Background,
            (SendOrPostCallback)delegate { StatusText.SetValue(TextBlock.TextProperty, status); }, null);
    }

    public void Finish()
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Background,
            (SendOrPostCallback)delegate { Close(); }, null);
    }
}

public interface IProgressContext
{
    void UpdateProgress(double progress);
    void UpdateStatus(string status);
    void Finish();
}

This is the imdb lookup method which uses the progressbar, this method uses an already existing xml list so it's only for updating data, not adding new movies:

public static void updateIMDBinfo()
    {

        //initialize progressbar
        ProgressDialog myProgressContext = new ProgressDialog();
        myProgressContext.Show();            

        //load old list
        List<Movie> movieList = XML.getMovieList();

        //create new updated list
        List<Movie> newMovieList = new List<Movie>();
        int count = 1;
        foreach (Movie movie in movieList)
        {
            //update progressbar
            myProgressContext.UpdateProgress((double)count / (double)movieList.Count);
            myProgressContext.UpdateStatus(String.Format("Updating movie: '{0}' ({1}/{2})", movie.Title, count, movieList.Count));

            movie.Link = movie.Link.Substring(movie.Link.IndexOf("http://www.imdb.com/title/") + 26, 9);

            //this creates a new movie where it looks up the data from imdb
            newMovieList.Add(new Movie(movie.Title, movie.Link, movie.Path));

            count++;
        }

        //sort the list
        newMovieList.Sort((Movie m1, Movie m2) => m1.Title.CompareTo(m2.Title));

        //save as xml
        XML.updateMovieList(newMovieList);

        //finish progressbar
        myProgressContext.Finish();
    }

So now when i use the method it opens the progressbar, but the bar never fills, it just keeps adding movies to the list and looking up the updated info without filling the bar. I thought by using it in a different threat would fix this problem?

Any ideas?

Thanks a bunch

Edit:

I tried using the BackgroundWorker. I added a background worker to my method and returned a ReportProgress back. I also added a backgroundWorker to my main class which uses the method, with eventhandlers. It didn't work however. I'm not very familiar with different threats. How should I go about then? I tried it like in here:

http://msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx

+6  A: 

Since you are in the same thread as the UI, the progress bar does not refresh, in fact the whole window is not refreshed because your operation blocks the main UI thread.

Look at the BackgroundWorker Component to load your movie list, it contains everything you need.

Gabriel Mongeon
I Added the link to the MSDN Doc.
Gabriel Mongeon
A: 

It appears that the issue is that the updateIMDBinfo call is tying up your UI thread. See the MSDN docs for the Thread or ThreadPool classes for launching that process -- then the dispatches to update the progress bar can progress unimpeded on the UI thread.

What I would guess is happening now is that your progress bar is empty, and then suddenly full when you're done. All those dispatches are queued up waiting for control to be returned from the current message processor, but the it's not returning because it's tied up with the actual work.

Clyde