GUI не обновляется до завершения кода - PullRequest
7 голосов
/ 18 октября 2010

Эй, у меня есть последовательность кода, которая выглядит примерно так:

label.Text = "update 0";
doWork();
label.Text = "update 1";
doWork2();
label.Text = "update 2";

По сути, графический интерфейс вообще не обновляется, пока весь код не будет выполнен.Как это побороть?

Ответы [ 4 ]

16 голосов
/ 18 октября 2010

Гадкий хак должен использовать Application.DoEvents.Хотя это работает, я бы посоветовал против этого.

Лучшим решением является использование BackgroundWorker или отдельного потока для выполнения долгосрочных задач.Не используйте поток GUI, потому что это приведет к его блокировке.

Важно помнить, что изменения в GUI должны быть внесены в поток GUI, поэтому вам необходимо передать управление обратно вГрафический интерфейс для обновления ярлыков.Это делается с помощью Invoke.Если вы используете BackgroundWorker, вы можете использовать ReportProgress - он будет автоматически обрабатывать вызов Invoke для вас.

2 голосов
/ 18 октября 2010

Пользовательский интерфейс обновляется, когда он получает сообщение WM_PAINT о перерисовке экрана.Если вы выполняете свой код, подпрограмма обработки сообщений не выполняется.

Чтобы включить выполнение обработчика сообщений, вы можете сделать следующее:

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

1 голос
/ 18 октября 2010

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

У вас есть несколько вариантов здесь:

  • переместить обработку в другой поток и вызвать ситуации Invoke ()
  • вызовите DoEvents () и разрешите обновлять графический интерфейс между вашими вызовами DoWork
  • сделать всю работу и обновить позже
1 голос
/ 18 октября 2010

В настоящее время вся ваша обработка выполняется в основном потоке (UI), поэтому вся обработка должна завершиться до того, как поток UI получит свободные циклы для перекраски UI.

У вас есть 2 способа преодолеть это. Первый способ, который не рекомендуется, это использовать
Application.DoEvents(); Запускайте это всякий раз, когда вы хотите, чтобы очередь сообщений Windows обрабатывалась.

Другой рекомендуемый способ: создать другой поток для обработки и использовать делегат для передачи обновлений пользовательского интерфейса обратно в поток пользовательского интерфейса. Если вы новичок в многопоточной разработке, попробуйте BackgroundWorker.

...