VisualizeIt!
Postad av Per i C#, ProcessIt!, Programmering, tags: C#, ProcessIt!, programmingVill du diskutera detta inlägg? Gör då det i forumet!
De visa säger att en bild säger mer än tusen ord och det brukar stämma. Så istället för att beskriva hur den tidigare nämnda klienten kommer att se ut, så visar jag därför en bild istället.
Kanske inte ser så mycket ut för värden just nu, men det ger er en ide om var det är på väg. Som synes är det MDI (Multi Document Interface) som gäller - dvs flera vyer kan öppnas i programmet, t.ex. 1-Wire schema, temperaturgrafer mm.
Så vad har jag gjort de senaste två dagarna? Ritat den supersnygga gröna ikonen? Jajamensan!
Nä, allvarligt talat så har jag spenderat min tid med att komma runt ett problem som bara måste lösas; multitrådning i en visuell applikation. En del av er kanske inte vet vad jag pratar om nu, men för er som vet så tänker jag fortsätta att pladdra
(det är dessutom ett bra sätt för mig att bearbeta mina tankar!)
Som bekant ska applikationen kunna visa flera olika vyer samt presentera olika typer av data, samt hantera användarens klickningar osv. Eftersom det från kärnan kan komma information sporadiskt (nej, jag vill inte använda pollning - det är fegt!
) så måste applikationen hela tiden vara beredd på att hantera denna information och samtidigt inte “låsa sig”, dvs sluta svara på användarens kommandon - det finns inget mer frustrerande för en användare än en applikation som “hänger sig”, även om det bara handlar om en halv sekund. För att komma runt detta använder jag multitrådning. Detta innebär att alla bearbetningsprocesser körs i bakgrunden, medan användaren glatt kan klicka vidare.
Det låter ju inte så svårt, eller hur? Det är det inte heller, men nu blir det knepigare. När informationen bearbetats färdigt ska den presenteras för användaren i ett fönster eller på annat sätt. Det är detta steg som jag jobbat på de senaste dagarna - problemet är att det ramverk jag använder, Microsoft .NET, inte tillåter att man uppdaterar visuella komponenter från anda trådar än programmets huvudtråd (det går att ignorera denna begränsning, men det är *inte* en bra idé). Så vad kan man göra då?
Alernativ 1:
if( InvokeRequired ) {
visualComponent.BeginInvoke( new MethodInvoker( DoTheWork ) );
}
else {
DoTheWork();
}
Denna lösning funkar, men det blir en väldig massa extra kod - man använder ju fler än en metod per komponent….så nej, bättre lösning måste finnas.
Alternativ 2:
Skapa egna varianter av de komponenter man vill använda och utgå från det som finns genom arv. Denna lösning fungerar också, och jag har t.ex. använt den i Temperaturkoll. Tyvärr bygger den delvis på alternativ 1, så även detta ger en stor mängd extra kod….så nej, det måste finnas en ännu bättre lösning.
Alternativ 3:
Alla Windows program bygger på grundprincipen att det finns något som kallas meddelandekö (Engelska: message pump) i programmet. Så är det även då man använder .NET, fastän den inte är lika tydligt exponerad. Efter två dagars experimenterande har jag nu kommit fram till att det bästa sättet att få saker och ting att fungera, utan att skriva en massa onödig kod, är att utnyttja denna meddelande kö till att be programmetshuvudtråd att utföra de önskade kommandona med hjälp av en synkroniserad kö där den kan hämta den information som ska visas. Naturligt vis läggs ingen logik-hantering i detta då vi ju är i den så kallade vyn (se [url=http://en.wikipedia.org/wiki/Model-view-controller]Model-View-Controller[/url]), dvs i presentationslagret.
Mins du en gröna ikonen jag nämnde i början av detta inlägg? Den styrs enligt alternativ tre och är bevis på att mina design fungerar vilket, om jag får vara ärlig, känns skönt - jag vill ju implementera funktioner, inte lösa ett problem som jag tycker Microsoft borde ha tagit fram en lösning på redan vid designen av ramverket. Kanske de gjort det i senare versioner (3.0 & 3.5)?
Alternativ 4:
Vet du ett bättre sätt att göra detta? Snälla, berätta!
Har du läst allt ovanstående? Bra jobbat, kanske lärde du dig något
Inlägg (RSS)