Jeg har en grafiktung applikation "MyApp", der skal overvåges af en anden applikation "Monitor". Begge er GUI-apps, dvs. de bruger Windows forms, og sidstnævnte skal bruges til at vise information om, hvad MyApp laver her og nu. Jeg kompilerer den som en .dll, fordi så kan MyApp lave en instans af den således:
Og det virker rent faktisk. Når jeg starter MyApp, dukker Monitor-app'en frem, som den skal, og MyApp kan med jævne mellemrum sende data til Monitor (igennem mit IMonitor-interface), som præsenterer dem for brugeren.
Så langt så godt.
Problemet er, at de kører i samme tråd (skulle jeg mene?), og det betyder, at hvis Monitor laver et eller andet "tungt", så fryser MyApp. Bare det, at jeg med musen flytter rundt på Monitor får MyApp til at fryse, indtil jeg slipper museknappen.
Hvordan undgår jeg det? Jeg tænkte, at jeg måske kunne starte Monitor i en anden tråd (med lav prioritet), men jeg kan ikke rigtigt få det til at virke. Enten når jeg lige at få et ganske kort glimt af Monitor, inden den forsvinder, eller også "hænger" den bare. Forslag modtages hjertens gerne! :)
Du bør nok kigge på BackgroundWorker til at lave det tunge arbejde.
Du får intet ud af at lave en Monitor sådan som du gør det. Hvis du vil have at din GUI er responsiv imens du udfører arbejde, så er der ingen vej udenom at køre multitrådet. Og det er BackgroundWorker perfekt til.
"Det du har brug for er at din monitor kører i et andet AppDomain. Eksemplet viser nøjagtigt hvad du skal gøre... "
Hm, hvorfor har jeg brug for det? Det er en lidt anden måde at instantiere min Monitor på i forhold til min nuværende metode:
// Metode 1: (den jeg bruger nu) Assembly asm = Assembly.Load( "MonitorAppDll" ); System.Object obj = asm.CreateInstance("MonitorAppDll.MonitorAppDll" );
// Metode 2: (den lavede jeg efter at have læst artiklen, du linkede til) AppDomain ad = AppDomain.CreateDomain( "MyDomain" ); System.Object obj = ad.CreateInstanceAndUnwrap( "MonitorAppDll", "MonitorAppDll.MonitorAppDll" );
Begge metoder virker som sådan, men jeg kan ikke se, hvad jeg vinder ved at bruge den ene fremfor den anden. De har begge det samme problem, at når jeg klikker på Monitor-vinudet for at flytte det, så fryser den anden app. indtil jeg slipper museknappen igen.
Det problem har jeg i øvrigt også, selvom jeg bruger en BackgroundWorker, når jeg skal opdatere min Monitor-UI.
Grunden til at jeg forslår en særskilt AppDomain til din Monitor er at den med sikkerhed ikke gør at din MyApp bliver forstyrret af Monitor. Selvfølgelig skal de deles om cpu ressourcerne, så hvis Monitor bruger meget cpu, vil MyApp ikke få helt så mange ressourcer som den plejer. Men jeg tror måske at du skal se på om måden du kommunikerer mellem de to, gør at MyApp ser ud til af fryse. Bruger du et synkront kald, hvor den venter på at komme retur?
Ja, det er synkron kommunikation, MEN det er meget få data, der skal overføres (et par hundrede bytes måske), og det sker kun hvert 2. sekund ca., så det er næppe det, der er flaskehalsen.
Når Monitor skal præsentere data for brugeren, kan det godt blive lidt tungt, fordi vi potentielt snakker om et par tusind (!) labels, der skal opdateres, og de labels befinder sig på et FlowlayoutPanel. Til det formal er en BackgroundWorker ganske anvendelig, som Bitmatic også pågeger. En yderligere optimering er at kalde SuspendLayout på panelet inden jeg opdaterer de mange labels.
Jeg tror faktisk, det eneste problem (som vel egentlig er mere et irritationsmoment end en showstopper) er, at begge vinduer "hænger", når jeg flytter eller resizer et af dem. Men måske er der ikke en vej uden om det udover at lade dem køre i hver sin process?
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.