Другой общий случай, когда можно получить это исключение, включает в себя насмешливые классы во время модульного тестирования. Независимо от используемой насмешливой структуры, вы должны убедиться, что все соответствующие уровни иерархии классов должным образом высмеиваются. В частности, все свойства HttpContext
, на которые ссылается тестируемый код, должны быть изделены.
См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.
В этом проблема:
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
.
Вы должны выполнить методы элемента управления из потока, который их создал. Чтобы обновить их из другого потока, используйте Invoke . Пример того, как это можно сделать, можно найти здесь здесь . Вы также должны прочитать многопоточность с формами и элементами управления в MSDN.
Вы получаете доступ к своей метке - которая была создана в потоке графического интерфейса пользователя - изнутри вашей рабочей папки. Доступ к элементу управления Windows из потока, отличного от того, на котором был создан элемент управления, не разрешен; поэтому вам предоставляется исключение.
Вы не должны обращаться к ярлыку напрямую, но вместо этого вы должны поднять событие из своего потока, и убедиться, что он вызван в правильном потоке, - который сигнализирует интерфейс так что вы можете изменить содержимое метки.
использовать этот код iw будет работать
BeginInvoke((MethodInvoker)delegate
{
TextBox1.Text += "your text here";
});