Событие ProgressChanged
возникает в потоке пользовательского интерфейса, а не в рабочем потоке. В вашем коде рабочий поток почти ничего не делает (просто цикл от 0 до 10000 и вызов ReportProgress
), большая часть работы выполняется в потоке пользовательского интерфейса. По сути, вы отправляете слишком много уведомлений о прогрессе. Из-за этого поток пользовательского интерфейса почти всегда занят и не имеет времени для визуализации нового содержимого метки.
Рендеринг в WPF выполняется не сразу при изменении свойства элемента управления, он выполняется в отдельном кадре диспетчера, который обрабатывается, когда диспетчеру не нужно делать что-либо более срочное в зависимости от приоритета задачи. Приоритет, используемый для рендеринга, имеет значение 7 (DispatcherPriority.Render
); событие ProgressChanged
передается в поток пользовательского интерфейса с приоритетом 9 (DispatcherPriority.Normal
), , как указано в MSDN . Таким образом, уведомления ProgressChanged
всегда имеют более высокий приоритет, чем рендеринг, и, поскольку они продолжают поступать, диспетчер никогда не успевает обработать задачи рендеринга.
Если вы просто уменьшите частоту уведомлений, ваше приложение должно работать нормально (в настоящее время вы отправляете 100 уведомлений для каждого значения в процентах, что бесполезно):
void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 10000; i++)
{
if (i % 100 == 0)
bw.ReportProgress(i / 100);
}
}