BackgroundWorker и Progressbar.Show()

Я использую Visual Studio 2010 и С# и пытаюсь показать индикатор выполнения, но это не работает.

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

Вот что я делаю:

static void Main(string[] args) {
  ProgressForm form = new ProgressForm();
  new FileWatcher(form).Start();
  Application.Run();
}

ProgressForm:
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
private void bgWorker_DoWork(object sender, DoWorkEventArgs e) {
  this.Show();
  ....
}

но ничего не показывает. Почему это не работает?

спасибо, пока, Юрген


person Juergen    schedule 10.06.2010    source источник


Ответы (3)


Вы не можете использовать BGW для отображения формы, поток не имеет надлежащего состояния. Вам нужно будет использовать Thread, чтобы вы могли вызвать его метод SetApartmentState(), чтобы переключить его на STA. Вам также нужен цикл сообщений в потоке, чтобы поддерживать форму в рабочем состоянии, для чего требуется вызов Application.Run(). И форма должна быть создана на этом потоке. Таким образом:

        var t = new Thread(() => Application.Run(new Form1()));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();

Одна большая проблема с этой формой заключается в том, что она не может принадлежать ни одному окну в потоке пользовательского интерфейса. Придание ему тенденции скрываться за окном другого приложения. Кроме того, ваш поток пользовательского интерфейса все еще мертв, его окна будут отображаться с сообщением «Не отвечает» в строке заголовка через несколько секунд.

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

person Hans Passant    schedule 10.06.2010
comment
Спасибо за помощь, ребята! Теперь это работает. Основная проблема заключалась в том, что я сделал это: Application.Run(); вместо этого: Application.Run(progressbarForm); И я вызываю индикатор выполнения из моего backgroundWorker, и он показывает! пока Юрген - person Juergen; 10.06.2010

Вы не должны изменять фоновые потоки формы пользовательского интерфейса. Это должно быть сделано только из основного потока. Вы можете показать основной индикатор выполнения непосредственно перед запуском фонового рабочего процесса и скрыть его в обработчике событий RunWorkerCompleted фонового рабочего процесса. Чтобы сообщить о реальном прогрессе, вам нужна реализация, как предложил Гиорги.

person Adrian Fâciu    schedule 10.06.2010
comment
это именно то, что я хочу сделать. но я наблюдаю за событием fileChangedEvent. это не поднимается в основной теме. - person Juergen; 10.06.2010
comment
Я делаю это: private void OnFileChanged(object source, FileSystemEventArgs e) { // Если я покажу здесь свой индикатор выполнения, ничего не произойдет this.backgroundWorker.RunWorkerAsync(); } - person Juergen; 10.06.2010
comment
Что значит ничего не происходит? Попробуйте запустить фонового работника backgroundWorker.RunWorkerAsync(); и на следующей строке показать индикатор выполнения. - person Adrian Fâciu; 10.06.2010

Чтобы сообщить о ходе выполнения из BackgroundWorker, вам необходимо вызвать метод ReportProgress из обработчика событий DoWork и показать ход выполнения в обработчике Событие BackgroundWorker.ProgressChanged

person Giorgi    schedule 10.06.2010
comment
Также я думаю, что вы должны установить для свойства ReportsProgress значение true. - person Thorsten Dittmar; 10.06.2010
comment
Я также попробовал событие progresschanged. Ничего не произошло. Но я хочу сначала показать свой индикатор выполнения, а затем установить прогресс. - person Juergen; 10.06.2010
comment
Я устанавливаю для ReportsProgress значение true, и событие возникает, но шоу ничего не делает. - person Juergen; 10.06.2010
comment
Вы должны показать индикатор выполнения, прежде чем начать работу из основного потока, и не трогайте его из фонового потока, как сказал Адриан в своем ответе. - person Giorgi; 10.06.2010