Можно ли «раскрутить» несколько потоков GUI? (Не останавливать систему на Application.Run)

Моя цель

Я хотел бы иметь основной поток обработки (не GUI) и иметь возможность раскручивать GUI в их собственных фоновых потоках по мере необходимости, и чтобы мой основной поток не GUI продолжал работать. Иными словами, я хочу, чтобы мой основной не GUI-поток был владельцем GUI-потока, а не наоборот. Я не уверен, что это возможно даже с Windows Forms (?)

Задний план

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

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

Время жизни всей системы выглядит следующим образом

  1. Приложение запускается.
  2. Проверьте файл конфигурации для загрузки компонентов. Загрузите их.
  3. Для каждого компонента запустите DoStuff()его инициализацию и заставьте его жить своей жизнью в своих собственных потоках.
  4. Продолжайте делать главное приложение-царь работы, навсегда.

Я еще не смог успешно выполнить пункт 3, если компонент запускает графический интерфейс DoStuff(). Он просто останавливается, пока графический интерфейс не будет закрыт. И только после закрытия графического интерфейса программа переходит к пункту 4.

Было бы здорово, если бы этим компонентам было разрешено запускать свои собственные графические интерфейсы Windows Forms.

проблема

Когда компонент пытается запустить графический интерфейс DoStuff()(точная строка кода - это когда компонент работает Application.Run(theForm)), компонент и, следовательно, наша система «зависают» на Application.Run()линии, пока графический интерфейс не будет закрыт. Хорошо, только что запущенный графический интерфейс работает нормально, как и ожидалось.

Пример комплектующих. Один не имеет ничего общего с GUI, а второй запускает милые окна с розовыми пушистыми кроликами в них.

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.
    }
}

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

public void DoStuff()
{
    new Thread(ThreadedInitialize).Start()
}

private void ThreadedInitialize()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form());
}

Можно ли раскрутить графический интерфейс и вернуться после Application.Run()?

5.08.2008 21:19:37
3 ОТВЕТА
РЕШЕНИЕ

Метод Application.Run отображает одну (или несколько) форм и запускает стандартный цикл обработки сообщений, который выполняется до тех пор, пока все формы не будут закрыты. Вы не можете форсировать возврат из этого метода, кроме как закрытием всех ваших форм или принудительным закрытием приложения.

Однако вы можете передать ApplicationContext (вместо новой Form ()) в метод Application.Run, и ApplicationContext можно использовать для запуска нескольких форм одновременно. Ваша заявка закончится только тогда, когда все они закрыты. Смотрите здесь: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

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

13
5.08.2008 21:45:17

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

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

Из-за этого более или менее предполагается, что если у вас есть какой-либо цикл обработки сообщений, он должен быть доступен в течение всего жизненного цикла вашего процесса. Например, Windows может отправить вам сообщение «Quit», и вам нужно иметь доступный цикл обработки сообщений, даже если у вас ничего нет на экране.

Лучше всего сделать это так:

Создайте поддельную форму, которая никогда не отображается, которая является вашим «основным приложением». Запустите Call Application.Run и передайте эту поддельную форму. Выполняйте свою работу в другом потоке и запускайте события в главном потоке, когда вам нужно делать что-то в Gui.

0
5.08.2008 23:22:00
На самом деле, окна связаны с потоками, а не процессами. Вы можете иметь несколько циклов сообщений на процесс, и это позволит вам иметь несколько совершенно независимых окон.
Garo Yeriazarian 7.09.2008 18:25:03

Я не уверен, что это правильно, однако я помню, как запускал оконные формы из консольного приложения, просто обновляя форму и вызывая для нее newForm.Show (), если ваши компоненты используют это вместо Application.Run (), тогда новый форма не должна блокировать.

Конечно, компонент будет отвечать за сохранение ссылки на формы, которые он создает.

0
23.05.2009 21:57:11