c# ProgressBar problem

こ雲淡風輕ζ 提交于 2020-01-05 04:59:26

问题


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(VS.95).aspx


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/1946377/c-sharp-progressbar-problem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!