Avatar billede MikkelNielsen Nybegynder
24. februar 2010 - 15:38 Der er 6 kommentarer

Spørgsmål vedr. threading i C#

Hey,

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:

Assembly asm = Assembly.Load( "MonitorAppDll" );
System.Object obj = asm.CreateInstance("MonitorAppDll.MonitorAppDll" );
mMonitor = (IMonitor)obj;
mMonitor.DoSomething();

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! :)
Avatar billede arne_v Ekspert
24. februar 2010 - 15:46 #1
Den er lidt tricky.

Tunge operationer skal laves paa en anden traad.

Men GUI skal laves paa event traaden.

Og det lyder som om at du har bundled de tunge ting og GUI i dit monitor modul.

Jeg er bange for at lidt redsign er noedvendigt.
Avatar billede bitmatic Nybegynder
24. februar 2010 - 16:02 #2
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.
Avatar billede mrtn Nybegynder
24. februar 2010 - 18:37 #3
Prøv at læse dette:
http://msdn.microsoft.com/en-us/library/3c4f1xde.aspx

Det du har brug for er at din monitor kører i et andet AppDomain. Eksemplet viser nøjagtigt hvad du skal gøre...
Avatar billede MikkelNielsen Nybegynder
25. februar 2010 - 13:04 #4
"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.
Avatar billede mrtn Nybegynder
25. februar 2010 - 18:50 #5
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?
Avatar billede MikkelNielsen Nybegynder
26. februar 2010 - 09:11 #6
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?
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester