Mulig å "spin off" flere grafiske tråder? (Ikke å stanse systemet ved Application.Run)

stemmer
20

Mitt mål

Jeg vil gjerne ha en hovedprosesseringstråd (ikke GUI), og være i stand til å spinne av GUI i sin egen bakgrunn tråder etter behov, og å ha min viktigste non GUI tråden fortsette arbeidet. Sagt på en annen måte, jeg vil ha min hoved ikke GUI-tråden for å være eier av GUI-tråden og ikke omvendt. Jeg er ikke sikker på at dette er også mulig med Windows Forms (?)

Bakgrunn

Jeg har en komponentbasert system i hvilket en styreenhet lastes sammenstillinger og forekomster og som er drevet klasser som implementerer en vanlig dynamisk IComponentgrensesnitt med en enkelt metode DoStuff().

Hvilke komponenter som blir lastet er satt opp via en XML-konfigurasjonsfil og ved å legge til nye sammenstillinger som inneholder forskjellige implementeringer av IComponent. Komponentene gir verktøyfunksjoner til hovedprogram. Mens hovedprogrammet gjør det ting, for eksempel å styre et atomkraftverk, kan komponentene utfører nytte oppgaver (i sine egne tråder), for eksempel rengjøring av databasen, sende e-post, skrive morsomme vitser på skriveren, hva har du. Det jeg ønsker, er å ha en av disse komponentene kunne vise en GUI, for eksempel med statusinformasjon for nevnte e-post sending komponent.

Levetiden til hele systemet ser slik ut

  1. Programmet starter.
  2. Sjekk konfigurasjonsfil for komponenter å laste. Laste dem.
  3. For hver komponent, kjøre DoStuff()for å initialisere den og gjøre den lever sitt eget liv i egne tråder.
  4. Fortsett å gjøre hovedprogram thingy kongen av arbeid, alltid.

Jeg har ennå ikke vært i stand til å utføre punkt 3 hvis komponenten fyrer opp et GUI i DoStuff(). Det rett og slett bare stopper inntil GUI er stengt. Og ikke før GUI er lukket gjør programmet videre til punkt 4.

Det ville være flott om disse komponentene fikk lov til å starte opp sin egen Windows Forms GUI.

Problem

Når en komponent prøver å fyre opp et GUI i DoStuff()(den eksakte kodelinje er når komponenten kjører Application.Run(theForm)), komponent og dermed våre system henger på Application.Run()linjen til GUI er stengt. Vel, bare fyrte opp GUI fungerer fint, som forventet.

Eksempel på komponenter. Man har ikke noe å gjøre med GUI, mens den andre branner opp en søt vinduer med rosa fluffy kaniner i dem.

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

Jeg har prøvd dette uten hell. Selv når jeg prøver å fyre opp GUI i sin egen tråd, stanser henrettelsen til GUI som lukket.

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

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

Er det mulig å spinne av en GUI og retur etter Application.Run()?

Publisert på 05/08/2008 klokken 21:19
kilden bruker
På andre språk...                            


3 svar

stemmer
11

Application.Run metode viser en (eller flere) danner og aktiverer standardmelding løkke som løper til alle former er lukket. Du kan ikke tvinge en retur fra at metoden unntatt ved å lukke alle skjemaene eller tvinge et program nedleggelse.

Man kan imidlertid passere en ApplicationContext (stansen av en ny form ()) for å Application.Run fremgangsmåte og ApplicationContext kan benyttes for å starte flere former samtidig. Din søknad vil bare ende når alle disse er lukket. Se her: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

Dessuten vil alle skjemaer som du viser ikke-modally fortsette å kjøre sammen med din viktigste formen, noe som vil gjøre deg i stand til å ha mer enn én vinduer som ikke blokkerer hverandre. Jeg tror dette er faktisk hva du prøver å oppnå.

Svarte 05/08/2008 kl. 21:45
kilden bruker

stemmer
0

Jeg er ikke sikker på om dette er riktig, men jeg husker kjører vindu former fra en konsoll applikasjon ved bare newing form og ringer newForm.Show () på det, hvis komponentene bruke den i stedet for Application.Run () da den nye skjemaet må ikke blokkere.

Selvfølgelig komponenten vil være ansvarlig for å opprettholde en referanse til skjemaene det skaper

Svarte 23/05/2009 kl. 21:57
kilden bruker

stemmer
0

Jeg er sikker på at dette er mulig hvis du hacke på det hardt nok, men jeg vil foreslå det ikke er en god idé.

'Windows' (som du ser på skjermen) er sterkt koblet til prosesser. Det vil si at hver prosess som viser noen GUI er forventet å ha en Message Loop, som behandler alle meldingene som er involvert med å opprette og administrere vinduer (ting som 'klikket på knappen', 'lukket app', 'oppdatere skjermen ' og så videre.

På grunn av dette, er det mer eller mindre forutsatt at hvis du har noen melding loop, må den være tilgjengelig for levetiden prosessen. For eksempel vinduer kan sende deg en 'slutte' -melding, og du må ha et budskap sløyfe tilgjengelig for å håndtere det, selv om du ikke har noe på skjermen.

Det beste alternativet er å gjøre det slik:

Lag en falsk form som aldri er vist som er din 'hoved app' Start Call Application.Run og passere i denne falske form. Gjøre arbeidet ditt i en annen tråd, og brann hendelser på hovedtråden når du trenger å gjøre Gui ting.

Svarte 05/08/2008 kl. 23:22
kilden bruker

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