Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > ProgressChanged event


Автор: lufton 4.3.2011, 21:20
Создал я класс. Один из методов по сути зализит на страницу по указанному адресу, парсит её и рекурсивно погружается (переходит) на один уровень глубже, при этом скачивая картинки с начальной страницы. Сделал я в этом классе событие:
Код

        public event GrabPageProgressChangeEvent GrabPageProgressChange;

        public void InvokeGrabPageProgressChange(GrabPageProgressChangeEventArgs args)
        {
            var handler = GrabPageProgressChange;
            if (handler != null) handler(this, args);
        }

Код

    internal delegate void GrabPageProgressChangeEvent(object sender, GrabPageProgressChangeEventArgs args);

    internal class GrabPageProgressChangeEventArgs
    {
        public double Progress;

        public GrabPageProgressChangeEventArgs(double progress)
        {
            Progress = progress;
        }
    }

В нужном месте и в нужное время вызываю InvokeGrabPageProgressChange, при этом передаю double значение прогресса. На форме создаю экземпляр объекта данного класса, подписываюсь на событие GrabPageProgressChange и вызываю упомянутый метод, так выглядит обработчик:
Код

        void GrabberGrabPageProgressChange(object sender, GrabPageProgressChangeEventArgs args)
        {
            progressBar1.Value = (int)args.Progress;
        }

Всё хорошо, срабатывает событие GrabPageProgressChange, срабатывает обработчик, но при попытке изменить значение progressbar вылетает исключение:
Цитата

Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "progressBar1" не из того потока, в котором он был создан.

Это очень интересно, ведь вроде бы всё правильно, и, я так понимаю, на то они и события, чтобы делать код красивым.
Подскажите пожалуйста, где ошибка.

Автор: lufton 5.3.2011, 09:42
Мне интересно, как тогда устроено аналогичное событие у WebBrowser? На сколько я помню, я свободно могу проделать аналогичную операцию с браузером, то есть, по изменению загрузки страницы прикрутить обработчик, который бы изменял значение ProgressBar. Вот только что попробовал и получилось. Как реализовать аналогичное?

Автор: -Mikle- 6.3.2011, 13:00
Нельзя работать с контролами формы из разных потоков. 
Это вам поможет:
Код

        void GrabberGrabPageProgressChange(object sender, GrabPageProgressChangeEventArgs args)
        {
            progressBar1.Invoke((Action)delegate
            {
                progressBar1.Value = (int)args.Progress;
            });
        }

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)