14. november 2008 - 15:33Der er
13 kommentarer og 3 løsninger
Er en timer god til at opdatere en GUI (threadsafe)
Har et program, der udover en GUI har et antal tråde, der udføre noget arbejde. I forbindelse med arbejdet skal der ske noget opdatering af GUI'en. Dette gør jeg for tiden ved at trådene ligger beskederne på en kø og via en timer opdaterer jeg GUI'en.
Mit spørgsmål, er så om dette er thread safe, eller om jeg skal bruge GUI objekternes invoke for at være sikker? Eller om der er andre metoder??
Med kunstig intelligens skaber HP’s nye OmniBook X 14 en unik og skræddersyet brugeroplevelse målrettet dem, der ønsker høj ydeevne og intelligente funktioner
I .NET 2.0+ er default at du får en exception hvis du forsøger at opdatere fra en anden tråd, så virker det så virker det. Check dog at din kø er thread safe - det checker .NET ikke for !
Hvis hovedtråden bliver sat til, at lave andre ting der kræver resourcer vil BackgroundWorker sidde pænt og vente på det bliver dens tur.
Hvor effektiv den er kommer derfor nok an på hvor avanceret GUI'en er. Hvis den er simpel vil BackgroundWorker fungere helt fint. Jeg kan høre der ikke flere ForeGround threads at konkurrere med andet end hovedtråden, men hvis dén bliver sat til at udføre noget "hårdt" arbejde kommer BackgroundWorker tråden til og vente lidt. Det selvfølgelig ikke sikkert det er kritisk i forhold til de GUI opdateringer der skal foretages.
Jo, man må vel antage at foreground er simpel da der idag (som jeg har forstået det) bruges en timer direkte herpå som opdaterer en statusbar eller noget.
Nu spørger jeg bare generelt. Er ikke relateret direkte til dette spørgsmål, men er normal fremgangsmåde ikke at man altid bruger en ny tråd når man udfører arbejde som er performance krævende? Man laver vel aldrig nogle store operationer i foreground og andre i background tråde?
Eller sagt på en anden måde, i hvilken situation kunne man forestille sig at en foreground tråd blev sat til at lave hårdt "fysisk" arbejde? Er det ikke dårlig programmering?
lasserasch -> Jeg har aldrig oplevet et Windows program, hvor der var tråde som skulle udføre tungt arbejde, som havde højere prioritet end UI tråden. Og jeg vil give dig ret i, at det lyder som at dårligt design at gøre det, da en sådan tråd vil fryse brugergrænsesnittet fuldstændigt. Og HELE brugergrænsesnittet bør opdateres af hovedtråden, og kun hovedtråden.
"Eller sagt på en anden måde, i hvilken situation kunne man forestille sig at en foreground tråd blev sat til at lave hårdt "fysisk" arbejde? Er det ikke dårlig programmering?"
I et dårligt design eller noget udviklet af en uerfaren programmør. Når en person stiller et spørgsmål angående tråde på eksperten må man antage han/hun ikke har meget erfaring med disse.
I øvrigt, så er jeg enig og skriver også at det ikke lyder som om der skulle være et problem med BackgroundWorker i den application der bliver udviklet her.
Jeg påpegede blot, at BackgroundWorker kun er aktiv når ForeGrounds threads tillader det. (det er i hvertfald min foreståelse).
Ok. Mit program består af en c++ dll (ikke dotnet), der udføre det egenlige arbejde. Min c# GUI applikation bruger så et interface til at kommunikere med denne dll. Når der sker en event i dll'en, som GUI, skal vise, tilføjes denne en kø (omgivet af criticalsection), som jeg så via en timer "tømmer" for beskeder ved hvert tick og opdatere GUI'en.
En anden ting jeg har lagt mærke til, er at det ser ud til at trådene kun bliver udført på en af kernerne (har en core duo 2 cpu)...
Jeg ved at hvis du benytter en ThreadPool, så håndtere Frameworket tråd delen rimelig optimalt for dig. Det vil sige, at den selv vil fordele tråde over de forskellige CPU kerner.
Den er meget nemt, at benytte.
men spørgsmålet er måske ved og løbe ud på et sidespor=). De forslag der er kommet til hvorledes du kan opdatere din GUI er helt ok.
Din egen kode er også fin nok, da det som sagt er hovedtråden der afvikle det event.
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.