Windows Forms - несколько циклов событий

У меня есть приложение Windows Forms (.NET), которое может одновременно открывать несколько документов.

Было бы удобно, если бы каждый документ (форма) выполнял свой собственный цикл обработки событий. После краткого экспериментирования кажется, что запуск нескольких циклов обработки событий в их собственных потоках STA работает. Есть ли причина, по которой это плохая идея?

Почему бы вам просто не запустить несколько экземпляров, по одному на документ?

Peter Wone 30.10.2008 01:10

Наше время запуска очень дорого, и мы хотели бы иметь возможность обмениваться документами без использования IPC.

fuzzyman 30.10.2008 21:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
2
1 907
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Просто будьте осторожны с доступом к элементам графического интерфейса из потоков.

Немодальные формы могут быть более подходящими для ваших целей. Используйте form.Show () вместо form.ShowDialog ().

+1 действительно. Разве все так не поступают? Таким образом вы можете показать столько форм, сколько захотите.

Wim Coenen 03.04.2009 02:33

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

fuzzyman 23.04.2009 17:52

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

MDI является ИЗБЫТОЧНЫМ с точки зрения пользователя, поскольку рабочий стол является контейнером MDI.

Peter Wone 30.10.2008 01:08

Почему вся эта ненависть к MDI ?? Все приложения MS Office являются MDI.

DJ. 30.10.2008 01:10

Word не использует MDI. Использование MDI затрудняет использование Excel - попробуйте открыть два документа на двух разных мониторах ...

fuzzyman 31.10.2008 02:36

В последних двух версиях приложения Office были мульти-SDI (что означает, что они позволяют рабочему столу служить контейнером MDI). Чтобы успокоить людей, которые не переносят изменений, есть переключатель конфигурации, который снова превращает их в приложения MDI, но я никогда не видел, чтобы он использовался.

Peter Wone 02.11.2008 15:26

Как вы думаете, почему вам нужно более одного цикла сообщений? Один цикл сообщений может обрабатывать любое количество окон.

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

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

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

fuzzyman 30.10.2008 21:23
Ответ принят как подходящий

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

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

И, как говорил Кевин, остерегайтесь межоконных (перекрестных) вызовов. Вы можете использовать Control.BeginInvoke или Control.Invoke для публикации вызовов делегатов в других потоках пользовательского интерфейса.

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

Еще одно преимущество, на которое стоит обратить внимание, - это то, что вы получаете один Application.ThreadException на цикл сообщений. Вы можете использовать это, чтобы логически «сгруппировать» вместе окна (например, все окна, принадлежащие одному логическому варианту использования / рабочему процессу), дать им выделенный поток и цикл сообщений и перехватывать необработанные исключения только из этих окон в Application.ThreadException этого потока.

stakx - no longer contributing 18.06.2014 11:30

Другие вопросы по теме