Możliwe „spin off” kilka wątków GUI? (Nie zatrzymanie systemu w Application.Run)

głosy
20

Mój cel

Chciałbym mieć główny wątek przetwarzania (bez GUI), i być w stanie wydzielić GUI w ich własnych wątków tła, ile potrzeba, i posiadające mój główny wątek GUI nie kontynuować pracę. Innymi słowy, chcę mój główny wątek non-GUI być właściciel GUI wątku, a nie odwrotnie. Nie jestem pewien, że to jest w ogóle możliwe z Windows Forms (?)

tło

Mam system oparty komponentowego, w którym kontroler dynamicznie załadować zespoły i instancję i prowadzić zajęcia wykonawczych wspólny IComponentinterfejs z jednej metody DoStuff().

Które składniki który jest ładowany jest skonfigurowany poprzez plik konfiguracyjny XML i dodając nowe zestawy zawierające różne implementacje IComponent. Składniki zapewnia funkcje użytkowe do głównej aplikacji. Podczas gdy główny program robi to rzecz, np sterowania elektrowni jądrowej, składniki mogą być wykonywanie zadań użytkowych (w ich własnych wątków), np czyszczenie bazy danych, wysyłanie wiadomości e-mail, drukowanie śmieszne drukarkę, co cię mieć. Chciałbym, ma mieć jeden z tych elementów w stanie wyświetlać GUI, np informacje o stanie dla wspomnianego komponentu e-mail wysyłanie.

Żywotność całego układu wygląda następująco

  1. uruchamia aplikację.
  2. Sprawdzić plik konfiguracyjny dla elementów do załadowania. Załadować je.
  3. Dla każdego komponentu, należy uruchomić DoStuff(), aby go zainicjować i sprawiają, że żyć własnym życiem w ich własnych wątków.
  4. Nadal do głównego aplikacji Thingy króla pracy, na zawsze.

I jeszcze nie były w stanie skutecznie wykonywać pkt 3, jeżeli składnik wystrzeliwuje się w GUI DoStuff(). To po prostu tylko zatrzymuje aż GUI jest zamknięta. I dopiero GUI jest zamknięty robi postępy programu do punktu 4.

Byłoby wspaniale, jeśli składniki te zostały dopuszczone do uruchomienia własnej Windows Forms GUI.

Problem

Gdy składnik próbuje odpalić w GUI DoStuff()(dokładna linia kodu jest, gdy składnik działa Application.Run(theForm)), komponent i stąd nasz system „zawiesza się” na Application.Run()linii aż GUI jest zamknięta. Cóż, po prostu wystrzelił w górę GUI działa dobrze, jak oczekiwano.

Przykład składników. Jeden ma nie ma nic wspólnego z GUI, podczas gdy drugi pożary górę słodkie okna z różowym puszyste króliczki w nich.

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

Próbowałem to bez powodzenia. Nawet gdy próbuję odpalić GUI w jego własnym wątku, wykonanie zatrzymuje aż GUI jako zamknięte.

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

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

Czy to możliwe, aby wydzielić GUI i powrót po Application.Run()?

Utwórz 05/08/2008 o 22:19
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
11

Application.Run sposób najmniej jedną (lub więcej) formy i inicjuje standardowego pętli wiadomość, która prowadzi aż wszystkie formy są zamknięte. Nie można wymusić powrót z tej metody tylko przez zamknięcie wszystkich formularzy lub wymuszając zamknięcie aplikacji.

Można jednak przekazać ApplicationContext (instad nowej formy ()) do metody Application.Run ApplicationContext i mogą być wykorzystane do uruchomienia kilku formach jednocześnie. Aplikacja będzie tylko kończy się, gdy wszystkie te są zamknięte. Zobacz tutaj: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

Ponadto, wszelkie formy, które można pokazać pojedynczymi blokami będą działać obok głównego formularza, który pozwoli Ci mieć więcej niż jednego okna, które nie blokują się nawzajem. Wierzę, że to jest rzeczywiście to, co staramy się osiągnąć.

Odpowiedział 05/08/2008 o 22:45
źródło użytkownik

głosy
0

Nie jestem pewien, czy to jest w porządku, jednak Pamiętam działa form okien z aplikacji konsoli po prostu newing formularz i wywołanie newForm.Show () na nim, jeśli składniki użyć że zamiast Application.Run (), a następnie nowy forma nie powinna blokować.

Oczywiście składnik będzie odpowiedzialny za utrzymywanie odniesienie do form tworzonych

Odpowiedział 23/05/2009 o 22:57
źródło użytkownik

głosy
0

Jestem pewien, że to jest możliwe, jeśli siekać na to wystarczająco trudne, ale sugeruję, że nie jest dobrym pomysłem.

„Windows” (który można zobaczyć na ekranie) są silnie sprzężone procesy. Oznacza to, że każdy proces, który wyświetla Oczekuje się, że każdy GUI mieć pętlę komunikatów, który przetwarza wszystkie wiadomości, które są zaangażowane w tworzenie i zarządzanie oknami (takie rzeczy jak „kliknięciu przycisku”, „zamknięte app”, „przerysowanie ekranu ' i tak dalej.

Z tego powodu jest on mniej lub bardziej przyjmuje się, że jeśli masz pętlę komunikatów, to musi być dostępny przez cały okres procesu. Na przykład okna może wysłać Ci wiadomość Quit, i trzeba mieć pętlę komunikatów dostępnych w obsłudze, że nawet jeśli nie masz nic na ekranie.

Najprościej jest to zrobić tak:

Zrobić fałszywy formularz, który nigdy nie jest pokazany, który jest Twój „głównym app” Start Up Call Application.Run i przekazać w tym fałszywego formularza. Zrobić swoją pracę w innym wątku i zdarzeń pożarowych w głównym wątku, kiedy trzeba zrobić Gui rzeczy.

Odpowiedział 06/08/2008 o 00:22
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more