![]() |
Модераторы: gambit, Partizan |
![]() ![]() ![]() |
|
Qwe2 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 23.3.2008 Репутация: нет Всего: нет |
Вопрос про поток и UI не новый, хочу уточнить несколько несложных моментов:
1) Я во втором потоке меняю значение контрола, напрмер так:
Если мне надо менять несколько контролов в другом потоке, то для каждого нужен свой делагат с методом? И как быть с самой формой: можно ли менять ее параметры (размер, положение, цвет фона) во втором потоке? 2) Как из второго потока динамически создать контрол (или несколько) на форме? 3) Могу ли я по окончанию асинхронного процесса, в методе CallBack, менять значения контролов на форме (вернее как)? И саму форму можно ли менять и создавать динамически другие контролы?
|
||||
|
|||||
jsharp36 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.10.2011 Репутация: 1 Всего: 1 |
Вы видимо не совсем понимаете, что есть главный поток в виндовс-приложении. Такое приложение в своей основе имеет бесконечный цикл с опрашиванием очереди сообщений. Нет сообщений - ничего не делает. Есть - начинает обрабатывать. Нажатие мышки или перетягивание формы, нажатие кнопки. Этот цикл скрыт. Программисты же пишут уже обработчики, которые вызываются в этом цикле. Именно поэтому, если обработчик выполняется долго, то приложение "не отвечает", если по нему тыкать мышкой. Конечно, не отвечает - потому как цикл остановился на одной итерации и отрабатывает обработчик и не выбирает новые сообщения от виндовс.
Чтобы корректно отрисовывалось и отрабатывало - все операции над формами и контролами надо производить в главном потоке. Что такое Invoke? Грубо можно представить, что тот главный цикл все время то обрабатывает сообщения, то засыпает, ничего не делая. Т.е. есть "дыры", когда он может приняться за вашу работу. Invoke для любого контрола или формы позволяет "вклинить" работу кода в главный поток. Исходя из этого по вопросам: 1)Kак хотите. Invoke для текстбокса - это захват главного потока. А там хоть большой кусок кода пишите, который формы меняет, другие контролы. 2) Пишете метод, который создает контролы и цепляет их на форму, но только вызываете метод через Invoke для формы - тоже, чтобы это произошло в главном гуи-потоке, чтобы корректно отработало, отрисовалось. 3) Всё, о чем надо заботиться, это чтобы работа с GUI была в главном потоке. Просто задавайте себе вопрос, в каком потоке работает метод. CallBack() в отличии от OnLoad работает не в главном потоке. Поэтому оттуда надо снова Invoke какого-то контрола или формы. Просто можно this.Invoke - т.к. класс формы. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Qwe2 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 23.3.2008 Репутация: нет Всего: нет |
Спасибо, многое прояснилось! На основании Вашего ответа получилось следующее (см. код), вопрос: почему визуально форма закрывается немного раньше, чем прогресс-бар доходит до максимума? Мне надо по завершении потока либо закрыть форму, либо что-то еще сделать с формой. Кстати, из вторичного потока можно закрывать форму или надо опять Invoke делать?
|
|||
|
||||
jsharp36 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.10.2011 Репутация: 1 Всего: 1 |
Всё нормально с прогресс-баром, я проверил. Он визуально немного отстает. Если уберете закрывание формы и поиграетесь цифрами в цикле, например, до 90 - то он остановится на 90. Если сотня - то он доходит до конца. Но немного опаздывает его прорисовка. Не знаю, зачем так сделано. Возможно, слишком быстрый цикл. Это не существенно, если вы будете прогресс баром отображать какие-то реальные процессы, за которыми можно будет следить.
Бегло погуглил, проблема известная. Я бы не парился. Если Вы собираетесь профессионально заниматься программированием под WinForms, то никто не пользуется их родными контролами. DevExpress почти без вариантов. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
jsharp36 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.10.2011 Репутация: 1 Всего: 1 |
Да, и нормальной практикой есть, даже не следить, из какого потока запускается. У контролов есть хитрое свойство. Можете понаписывать такие обертки:
И вызывать из любого потока не задумываясь Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
Для того, чтобы сделать маршалинг в поток UI возможно использовать не только Control.Invoke (или BeginInvoke) вызовы. Если у вас есть длительная операция, которая требует "уведомления" UI , то можно захватить в свой рабочий поток контекст синнхронизации (используя SynchronizationContext.Current при создании потока). Далее, для маршалинга использовать его методы (в зависимости от нужного поведения - Post или Send (Send блокирует поток до выполнения смаршаленного делегата). Более того: методы Control.Invoke тоже самое и делают.
аналогично п1. -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Разработка Windows Forms | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |