SSH / C # / BackgroundWorker | Ошибка нескольких потоков [дубликат]

Другой общий случай, когда можно получить это исключение, включает в себя насмешливые классы во время модульного тестирования. Независимо от используемой насмешливой структуры, вы должны убедиться, что все соответствующие уровни иерархии классов должным образом высмеиваются. В частности, все свойства HttpContext, на которые ссылается тестируемый код, должны быть изделены.

См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.

4
задан ebb 1 November 2011 в 12:55
поделиться

4 ответа

В этом проблема:

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.

11
ответ дан Jon Skeet 25 August 2018 в 06:56
поделиться

Вы должны выполнить методы элемента управления из потока, который их создал. Чтобы обновить их из другого потока, используйте Invoke . Пример того, как это можно сделать, можно найти здесь здесь . Вы также должны прочитать многопоточность с формами и элементами управления в MSDN.

0
ответ дан Bobson 25 August 2018 в 06:56
поделиться

Вы получаете доступ к своей метке - которая была создана в потоке графического интерфейса пользователя - изнутри вашей рабочей папки. Доступ к элементу управления Windows из потока, отличного от того, на котором был создан элемент управления, не разрешен; поэтому вам предоставляется исключение.

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

0
ответ дан Frederik Gheysels 25 August 2018 в 06:56
поделиться

использовать этот код iw будет работать

 BeginInvoke((MethodInvoker)delegate
               {
                   TextBox1.Text += "your text here";

               });
3
ответ дан vzades 25 August 2018 в 06:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: