В этом проблема:
label1.Text = i.ToString();
Вы пытаетесь изменить текст метки внутри BackgroundWorker
, который не работает в потоке пользовательского интерфейса. Точка BackgroundWorker
состоит в том, чтобы делать все не-UI-работу там, используя ReportProgress
, чтобы периодически «возвращаться» к потоку пользовательского интерфейса и обновлять пользовательский интерфейс с тем успехом, который вы делаете.
Поэтому либо вам нужно изменить label1.Text
в BwProgressChanged
, а также или , вам нужно использовать Control.Invoke
/ BeginInvoke
так же, как и на любом другом фоне thread:
// Don't capture a loop variable in a lambda expression...
int copy = i;
Action updateLabel = () => label1.Text = copy.ToString();
label1.BeginInvoke(updateLabel);
Подробнее о копировальной части см. в блоге Eric Lippert, «Закрытие переменной цикла считается вредным» . В этом конкретном случае это только проблема, потому что я использую BeginInvoke
. Этот можно было бы изменить на просто:
Action updateLabel = () => label1.Text = i.ToString();
label1.Invoke(updateLabel);
... но теперь фоновый рабочий всегда будет ожидать, пока пользовательский интерфейс догонит, прежде чем он продолжит движение, что в реальном жизнь обычно не то, что вы хотите. Обычно я предпочитаю BeginInvoke
по Invoke
.