Создание элементов управления в потоке без пользовательского интерфейса
=======================================================================

У меня есть своего рода модель плагинов, в которой различные сложные пользовательские элементы управления хранятся в DLL и загружаются и создаются во время выполнения с использованием

```
<code>Activator.CreateInstanceFrom(dllpath, classname).
</code>
```

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

Кажется, это работает нормально - пока я не попытаюсь установить какое-либо свойство для любого вложенного элемента управления на одном из этих пользовательских элементов управления, например в обработчике события кнопки, которая выдает исключение перекрестной потоковой обработки. Я действительно понимаю, что мог бы избежать этого, проверяя InvokeRequired каждый раз, когда я получаю доступ к свойству, но мне не нужно беспокоиться об этом при написании кода для пользовательских элементов управления (особенно, поскольку есть и другие, которые пишут эти кусочки кода, которые могут не всегда помню).

Поэтому у меня вопрос: есть ли какой-нибудь безопасный способ сделать то, что я пытаюсь сделать, или как мне лучше всего загружать эти элементы управления в фоновом режиме? Или это в принципе невозможно, и мне нужно придерживаться основного потока для создания элементов управления?

Я надеюсь, что предоставленной мною информации достаточно, чтобы прояснить мою ситуацию; если нет, я был бы рад разработать и предоставить примеры кода.

 ия в фоновом режиме, но элемент управления должен быть добавлен в форму в основном потоке, и все взаимодействие с пользователем, а также любое программное изменение свойств элемента управления (после его создания) имеет происходить в основном потоке. Как вы, наверное, уже знаете, просто невозможно обойти это. Теперь, если загрузка этих библиотек DLL и создание элементов управления не занимает много времени, я не вижу причин делать это в отдельных фоновых потоках.

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

 Попытка сделать универсальную универсальную среду, которая работает одинаково в режиме потока пользовательского интерфейса и в фоновом режиме и просто проверяет результаты InvokeRequired иногда вхуж производительность (поскольку все потоки заблокированы в Invoke) или даже в (необнаруженных) взаимоблокировках, как только приложение достигает разумной сложности. Также выполнение всех асинхронных обновлений в BeginInvoke, без учета каждого метода в отдельности, может привести к проблемам согласованности данных (т. Е. Элементы управления могут обновлять себя до состояний Назад вовремя из-за изменения порядка вызовов между потоками).



 я немного поэкспериментировал, и на деле вы можете установить большинство свойств в потоке, если он не был парентирован (т.е. добавлен в какое-либо свойство Control.Controls).

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

 Ред .: Я не думаю, что имеет значение, какой поток создал элемент управления. Поэтому должны применяться нормальные правила, т.е. вы можете работать только с элементами управления из основного потока Windows. И я думаю, что критерием является HandleCreated, а не Parented. Пока этого не произошло, вы получаете небольшую передышку.



  [этот ответ](https://stackoverflow.com/questions/906057/problem-with-delegate-syntax-in-c/906097#906097) предоставляет элегантный способ обойти эту проблему.

 Код цитируется из этого ответа:

 ... хотя в вашем случае вы захотите вызвать BeginInvoke для самих элементов управления: