Создание средств управления в потоке неUI

Используйте sleep примерно так:

sleep 2

Это будет спать в течение 2 секунд.

Будьте осторожны, чтобы привести аргумент. Если вы просто запустите sleep, процесс будет спать вечно. (Это полезно, когда вы хотите, чтобы поток спал, пока он не проснулся.)

7
задан Fredrik Mörk 24 June 2009 в 20:36
поделиться

3 ответа

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

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

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

3
ответ дан 7 December 2019 в 12:24
поделиться

Образец кода в этот ответ предлагает элегантный способ решения этой проблемы.

Цитата из этого ответа:

public void UpdateTestBox(string newText)
{
    BeginInvoke((MethodInvoker) delegate {
        tb_output.Text = newText;
    });        
}

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

public void UpdateTestBox(string newText)
{
    tb_output.BeginInvoke((MethodInvoker) delegate {
        tb_output.Text = newText;
    });        
}
1
ответ дан 7 December 2019 в 12:24
поделиться

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

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


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

1
ответ дан 7 December 2019 в 12:24
поделиться
Другие вопросы по тегам:

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