Is dit moontlik om verskeie GUI-drade te "afspin"?(Stak nie die stelsel by Application.Run nie)

StackOverflow https://stackoverflow.com/questions/2872

  •  08-06-2019
  •  | 
  •  

Vra

My doel

Ek wil graag 'n hoofverwerkingsdraad (nie GUI) hê, en GUI's in hul eie agtergronddrade kan afspin soos nodig, en dat my hoof nie-GUI-draad aanhou werk.Anders gestel, ek wil hê dat my hoof nie-GUI-draad die eienaar van die GUI-draad moet wees en nie andersom nie.Ek is nie seker dit is eers moontlik met Windows Forms(?)

Agtergrond

Ek het 'n komponent-gebaseerde stelsel waarin 'n kontroleerder samestellings dinamies laai en klasse instansieer en hardloop wat 'n algemene IComponent koppelvlak met 'n enkele metode DoStuff().

Watter komponente wat gelaai word, word gekonfigureer via 'n xml-konfigurasielêer en deur nuwe samestellings by te voeg wat verskillende implementerings van IComponent.Die komponente verskaf nutsfunksies aan die hooftoepassing.Terwyl die hoofprogram sy ding doen, bv.die beheer van 'n kernkragaanleg, kan die komponente nutstake verrig (in hul eie drade), bv.die databasis skoonmaak, e-posse stuur, snaakse grappies op die drukker druk, wat het jy.Wat ek graag wil hê, is dat een van hierdie komponente 'n GUI kan vertoon, bv.met statusinligting vir die genoemde e-posstuurkomponent.

Die leeftyd van die volledige stelsel lyk so

  1. Aansoek begin.
  2. Gaan die konfigurasielêer na vir komponente om te laai.Laai hulle.
  3. Vir elke komponent, hardloop DoStuff() om dit te inisialiseer en sy eie lewe in hul eie drade te laat leef.
  4. Gaan voort om die hooftoepassing-ding-koning van werk te doen, vir ewig.

Ek kon nog nie punt 3 suksesvol uitvoer as die komponent 'n GUI invuur nie DoStuff().Dit stop eenvoudig totdat die GUI gesluit is.En nie totdat die GUI gesluit is nie, vorder die program tot by punt 4.

Dit sal wonderlik wees as hierdie komponente toegelaat word om hul eie Windows Forms GUI's te begin.

Probleem

Wanneer 'n komponent probeer om 'n GUI in DoStuff() (die presiese reël kode is wanneer die komponent loop Application.Run(theForm)), die komponent en dus ons stelsel "hang" by die Application.Run() lyn totdat die GUI gesluit is.Wel, die pas aangevuurde GUI werk goed, soos verwag.

Voorbeeld van komponente.Een het niks met GUI te doen nie, terwyl die tweede 'n oulike venster met pienk donsige hasies in vuur.

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

Ek het dit probeer sonder sukses.Selfs wanneer ek probeer om die GUI in sy eie draad aan te blaas, stop die uitvoering totdat die GUI gesluit is.

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

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

Is dit moontlik om 'n GUI af te spin en daarna terug te keer Application.Run()?

Was dit nuttig?

Oplossing

Application.Run metode vertoon een (of meer) vorms en begin die standaard boodskaplus wat loop totdat al die vorms gesluit is.Jy kan nie 'n terugkeer vanaf daardie metode afdwing nie, behalwe deur al jou vorms toe te maak of 'n aansoek af te dwing.

Jy kan egter 'n slaag Aansoekkonteks (instad van 'n nuwe Form()) na Application.Run metode en ApplicationContext kan gebruik word om verskeie vorms gelyktydig te begin.Jou aansoek sal eers eindig wanneer almal gesluit is.Kyk hier: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

Ook, enige vorms wat jy nie-modaal wys, sal voortgaan om langs jou hoofvorm te loop, wat jou in staat sal stel om meer as een venster te hê wat mekaar nie blokkeer nie.Ek glo dit is eintlik wat jy probeer bereik.

Ander wenke

Ek is seker dit is moontlik as jy hard genoeg daaraan kap, maar ek sou voorstel dat dit nie 'n goeie idee is nie.

'Windows' (wat jy op die skerm sien) is hoogs gekoppel aan prosesse.Dit wil sê, elke proses wat enige GUI vertoon, sal na verwagting 'n Boodskaplus hê, wat al die boodskappe verwerk wat betrokke is by die skep en bestuur van vensters (dinge soos 'die knoppie geklik', 'die toepassing toegemaak', 'herteken die skerm ' en so aan.

As gevolg hiervan word daar min of meer aanvaar dat as jy enige boodskaplus het, dit vir die leeftyd van jou proses beskikbaar moet wees.Windows kan byvoorbeeld vir jou 'n 'hou'-boodskap stuur, en jy moet 'n boodskaplus beskikbaar hê om dit te hanteer, selfs al het jy niks op die skerm nie.

Jou beste weddenskap is om dit so te doen:

Maak 'n valse vorm wat nooit getoon word nie, wat u 'hoof -app' is, begin 'n oproep -toepassing en slaag hierdie vals vorm in.Doen jou werk in 'n ander draad, en brand gebeurtenisse by die hoofdraad wanneer jy Gui-dinge moet doen.

Ek is nie seker of dit reg is nie, maar ek onthou dat ek venstervorms vanaf 'n konsoletoepassing laat loop het deur net die vorm te nuwe en newForm.Show() daarop te roep, as jou komponente dit gebruik in plaas van Application.Run() dan die nuwe vorm moet nie blokkeer nie.

Natuurlik sal die komponent verantwoordelik wees vir die handhawing van 'n verwysing na die vorms wat dit skep

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top