C# Проблема с ProgressBar

Я искал способ создать хороший индикатор выполнения. Я нашел некоторый код, который я использовал, и он отлично работал, если я использовал цикл. Но теперь я хотел использовать его в действительно приличном приложении, и это доставило мне много хлопот. У меня есть приложение, в котором я ищу данные на IMDB, поэтому я подключаюсь к IMDB, например, для 500 названий фильмов, так что это занимает некоторое время. Поэтому я хотел показать индикатор выполнения, где полоса росла для каждого фильма, который он просматривал, и с некоторой дополнительной информацией о названии фильма.

Я использую следующий класс:

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();
}

Это метод поиска imdb, который использует индикатор выполнения, этот метод использует уже существующий список xml, поэтому он предназначен только для обновления данных, а не для добавления новых фильмов:

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();
    }

Итак, теперь, когда я использую этот метод, он открывает панель прогресса, но полоса никогда не заполняется, он просто продолжает добавлять фильмы в список и искать обновленную информацию, не заполняя полосу. Я думал, что использование его в другой угрозе решит эту проблему?

Любые идеи?

Огромное спасибо

Редактировать:

Я попытался использовать BackgroundWorker. Я добавил фонового работника в свой метод и вернул ReportProgress обратно. Я также добавил backgroundWorker в свой основной класс, который использует этот метод с обработчиками событий. Однако это не сработало. Я не очень хорошо знаком с различными угрозами. Как мне быть тогда? Пробовал как здесь:

http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspx


person WtFudgE    schedule 22.12.2009    source источник
comment
Я так понимаю, это приложение для Windows? не приложение asp.net?   -  person ram    schedule 22.12.2009


Ответы (2)


Поскольку вы находитесь в том же потоке, что и пользовательский интерфейс, индикатор выполнения не обновляется, фактически все окно не обновляется, поскольку ваша операция блокирует основной поток пользовательского интерфейса.

Посмотрите на компонент BackgroundWorker, чтобы загрузить список фильмов. , он содержит все, что вам нужно.

person Gabriel Mongeon    schedule 22.12.2009
comment
Я добавил ссылку на документ MSDN. - person Gabriel Mongeon; 22.12.2009

Похоже, проблема в том, что вызов updateIMDBinfo связывает ваш поток пользовательского интерфейса. См. документы MSDN для классов Thread или ThreadPool для запуска этого процесса — тогда отправки для обновления индикатора выполнения могут беспрепятственно выполняться в потоке пользовательского интерфейса.

Я предполагаю, что сейчас происходит то, что ваш индикатор выполнения пуст, а затем внезапно заполняется, когда вы закончите. Все эти отправки ставятся в очередь в ожидании возврата управления от текущего процессора сообщений, но он не возвращается, потому что связан с фактической работой.

person Clyde    schedule 22.12.2009