Я только что наткнулся на ту же проблему и нашел некоторую интересную информацию, и я хотел вставить свои два цента и добавить ее сюда.
Прежде всего, как уже упоминали другие, длительные операции должны выполняться потоком, который может быть фоновым работником, явным потоком, потоком из пула потоков или (начиная с .Net 4.0) задачей: Stackoverflow 570537: обновлять метки при обработке в окнах , чтобы пользовательский интерфейс оставался отзывчивым.
Но для коротких задач нет необходимости в многопоточности, хотя это, конечно, не повредит.
Я создал winform с одной кнопкой и одной меткой для анализа этой проблемы:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
label1->Text = "Start 1";
label1->Update();
System::Threading::Thread::Sleep(5000); // do other work
}
Мой анализ перешагнул через код (используя F10) и увидел, что произошло. И после прочтения этой статьи Многопоточность в WinForms я обнаружил кое-что интересное. В статье в нижней части первой страницы говорится, что поток пользовательского интерфейса не может перерисовать пользовательский интерфейс до тех пор, пока текущая выполняемая функция не завершится и Windows не помечает окно как «не отвечающее» через некоторое время. Я также заметил, что в моем тестовом приложении сверху, хотя шагая через него, но только в определенных случаях.
(Для следующего теста важно не устанавливать полноэкранный режим Visual Studio, вы должны одновременно видеть рядом с ним свое маленькое окно приложения. Вам не нужно переключаться между окном Visual Studio для отладка и окно вашего приложения, чтобы увидеть, что происходит. Запустите приложение, установите точку останова на label1->Text ...
, поместите окно приложения рядом с окном VS и поместите курсор мыши на окно VS.)
Когда я нажимаю один раз на VS после запуска приложения (чтобы поместить фокусы туда и включить пошаговое управление) и шагаю по нему БЕЗ перемещения мыши, устанавливается новый текст и метка обновляется в обновлении () function. Это означает, что пользовательский интерфейс перекрашивается явно.
Когда я перехожу через первую строку, затем многократно двигаю мышь и щелкаю куда-то, затем шагаю дальше, вероятно, устанавливается новый текст и вызывается функция update (), но пользовательский интерфейс не обновляется / перекрашивается и старый текст остается там до завершения функции button1_click (). Вместо перекраски окно помечается как "не отвечающее"! Также не помогает добавление this->Update();
для обновления всей формы.
Добавление Application::DoEvents();
дает интерфейсу возможность обновлять / перекрашивать. В любом случае вы должны позаботиться о том, чтобы пользователь не мог нажимать кнопки или выполнять другие операции с пользовательским интерфейсом, которые не разрешены! Поэтому: Старайтесь избегать DoEvents ()! , лучше используйте многопоточность (что, я думаю, довольно просто в .Net).
Но ( @ Jagd, 2 апреля 2010 года в 19: 25 ) вы можете опустить .refresh()
и .invalidate()
.
Мои объяснения следующие: AFAIK winform все еще использует функцию WINAPI. Также Статья MSDN о методе System.Windows.Forms Control.Update относится к функции WINAPI WM_PAINT. В статье MSDN о WM_PAINT в первом предложении говорится, что команда WM_PAINT отправляется системой только тогда, когда очередь сообщений пуста. Но поскольку очередь сообщений уже заполнена во втором случае, она не отправляется, и поэтому метка и форма заявки не перекрашиваются.
<> joke> Вывод: так что вам просто нужно запретить пользователю использовать мышь ;-) <> / joke>