C # многопотоковая операция недопустима, 2 элемента управления и 2 отдельных потока - PullRequest
2 голосов
/ 07 декабря 2011

Вот упрощенный пример того, что я пытаюсь сделать:

У меня есть 2 элемента управления MyControl c и Panel p. p создается в основном потоке GUI как обычно, но я хочу, чтобы c создавался в фоновом потоке, потому что это занимает некоторое время, и я не хочу замораживать графический интерфейс. Как я могу добавить c к p.Controls? Если я делаю это в this.Invoke, оно выдает исключение для c, а если я делаю это из фонового потока, оно выдает исключение для p.

Или мне не следует создавать элементы GUI вне основного потока GUI?

Ответы [ 3 ]

3 голосов
/ 07 декабря 2011

Или я действительно не должен создавать элементы GUI вне основного потока GUI?

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

Как правило, способ справиться с этим - переместить «работу», которая вызывает медленное создание элемента управления, в фоновый поток,но все же создайте элемент управления в потоке пользовательского интерфейса.Затем вы будете использовать Control.Invoke или Control.BeginInvoke для обновления информации в пользовательском интерфейсе после завершения медленной работы.

Например, если вы загружаете набор данных из какого-либо внешнего источника, выМожно создать элемент управления и запустить фоновый поток для загрузки данных.После загрузки данных вы можете , а затем обновить элемент управления, чтобы отразить его.Это заставит его оставаться отзывчивым все время.

1 голос
/ 07 декабря 2011

Используйте фоновый поток, чтобы сделать то, что он должен сделать, и затем как-то подать сигнал (bool _backgroundCompleted в качестве тривиального примера), что c готов к созданию.

Создать c из Timer он будет периодически запускаться и ничего не делать, пока не будет установлено _backgroundCompleted, затем создайте c, затем убьете таймер.

Это может быть "некрасиво", но будет работать и останется простым.

Forms.Timer, если вы спрашиваете;)

И да, НИКОГДА никогда не связывайтесь с несколькими потоками в одной форме.Вы можете иметь несколько форм в нескольких потоках, но для этого вам нужно сначала ЗАПУСТИТЬ новый поток, а затем создать форму НА нем.Он будет иметь свой собственный цикл обработки сообщений и будет работать нормально.

1 голос
/ 07 декабря 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...