Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
899
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Возможно "spin off" несколько GUI потоков? (Не останавливая систему на Application.Run)
Моя Цель
Я хотел бы иметь основной поток обработки (не GUI) и иметь возможность выделять GUIs в своих собственных фоновых потоках по мере необходимости, а мой основной поток не GUI продолжает работать. Другими словами, Я хочу, чтобы мой основной не GUI-поток был владельцем GUI-потока, а не наоборот. Я не уверен, что это возможно даже с формами Windows (?)
Фон
У меня есть система на основе компонентов, в которой контроллер динамически загружает сборки и создает экземпляры и запускает классы, реализующие общий интерфейс IComponent с одним методом DoStuff() .
Какие компоненты, которые загружаются, настраиваются с помощью файла конфигурации xml и путем добавления новых сборок, содержащих различные реализации IComponent . Компоненты предоставляют служебные функции главному приложению. В то время как основная программа делает это вещь, например управляя ядерной установкой, компоненты могут выполнять служебные задачи (в своих собственных потоках), например, очищать базу данных, отправлять электронные письма, печатать смешные шутки на принтере, что у вас есть. Я бы хотел, чтобы один из этих компонентов мог отображать GUI, например, с информацией о состоянии для указанного компонента отправки email.
Время жизни всей системы выглядит следующим образом
- Запуск приложения.
- Проверьте файл конфигурации для загрузки компонентов. Загружать их.
- Для каждого компонента запустите
DoStuff(), чтобы инициализировать его и заставить его жить своей собственной жизнью в своих собственных потоках. - Продолжать делать основное применение-штука царем работать, навсегда.
Я еще не смог успешно выполнить пункт 3, если компонент запускает GUI в DoStuff() . Он просто останавливается, пока GUI не будет закрыт. И только после закрытия GUI программа переходит к пункту 4.
Было бы здорово, если бы этим компонентам было разрешено запускать свои собственные формы Windows GUIs.
Проблема
Когда компонент пытается запустить GUI в DoStuff() (точная строка кода - это когда компонент запускает Application.Run(theForm)), компонент и, следовательно, наша система "hangs" в строке Application.Run() , пока GUI не будет закрыт. Ну, только что загорелся GUI работает нормально, как и ожидалось.
Пример компонентов. Один не имеет ничего общего с GUI, в то время как второй запускает симпатичный windows с розовыми пушистыми кроликами в них.
public class MyComponent1: IComponent
{
public string DoStuff(...) { // write something to the database }
}
public class MyComponent2: IComponent
{
public void DoStuff()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
// I want the thread to immediately return after the GUI
// is fired up, so that my main thread can continue to work.
}
}
Я пробовал это без удачи. Даже когда я пытаюсь запустить GUI в своем собственном потоке, выполнение останавливается до тех пор, пока GUI не будет закрыт.
public void DoStuff()
{
new Thread(ThreadedInitialize).Start()
}
private void ThreadedInitialize()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
Можно ли открутить GUI и вернуться после Application.Run() ?
Application.Run метод отображает одну (или несколько) форм и инициирует стандартный цикл сообщений, который выполняется до тех пор, пока все формы не будут закрыты. Принудительный возврат из этого метода возможен только при закрытии всех форм или принудительном завершении работы приложения.
Однако можно передать метод ApplicationContext (вместо нового Form()) в метод Application.Run, а метод ApplicationContext можно использовать для запуска нескольких форм одновременно. Ваше приложение завершится только тогда, когда все они будут закрыты. Смотрите здесь: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx
Кроме того, любые формы, которые вы показываете немодально, будут продолжать работать вместе с вашей основной формой, что позволит вам иметь более одного windows, которые не блокируют друг друга. Я считаю, что это на самом деле то, что вы пытаетесь достичь.
Я уверен, что это возможно, если вы взломаете его достаточно сильно, но я бы предположил, что это не очень хорошая идея.
'Windows' (которые вы видите на экране) сильно связаны с процессами. То есть, каждый процесс, который отображает любой GUI, как ожидается, будет иметь цикл сообщений, который обрабатывает все сообщения, связанные с созданием и управлением windows (такие вещи, как "нажал кнопку", "закрыл приложение", "перерисовать экран" и так далее.
Из-за этого более или менее предполагается, что если у вас есть какой-либо цикл сообщений, он должен быть доступен в течение всего срока службы вашего процесса. Например, windows может отправить вам сообщение 'quit', и вам нужно иметь доступный цикл сообщений для обработки этого, даже если у вас ничего нет на экране.
Лучше всего сделать это вот так:
Сделайте поддельную форму, которая никогда не показывается, которая является вашим 'main app' Запускать Позвоните Application.Run и передайте в этой поддельной форме. Выполняйте свою работу в другом потоке и запускайте события в основном потоке, когда вам нужно сделать материал Gui.
Я не уверен, что это правильно, однако я помню, как запускал оконные формы из консольного приложения, просто создавая форму и вызывая newForm.Show() на ней, если ваши компоненты используют это вместо Application.Run(), то новая форма не должна блокировать.
Конечно, компонент будет отвечать за поддержание ссылки на формы, которые он создает