Addeladder skrev:
Application.DoEvents(); finns men förhindrar inte från att applikationen ska sluta svara under tiden.
Nope inte under tiden som du gör anropet till databasen, men om du lägger det efter anropet i din loop, så hinner applikationen få lite väntetid innan nästa anrop görs. Men om det hjälper har jag faktiskt ingen anning om, det är bara på pappert det ser bra ut ;)
addeladder skrev:
Det bästa är så klart att köra allting i en ny tråd.
Verkar dock vara rätt så klurigt att köra saker trådat? Eller har jag fått allt om bakfoten.
Det är inga problem med att köra saker trådat, bara att lägga koden som du vill få exekverat i en egen tråd i en funktion, så sedan använder du följande kod för att starta tråden.
Thread myThread = new Thread(new ThreadStart(HÄR SKRIVER DU IN NAMNET PÅ FUNKTIONEN));
myThread.Bakgroundthread = true;
myThread.Name = "My Thread";
myThread.Start;
Så nu gör all kod i din funktion i en egen tråd, enkelt va!?!?!?.
MEN, MEN, MEN... nu börjar problemen med multitrådade applikationer. Dels så får du inte uppdaterar något i din applikationsGUI från din tråd, du får alltså inte skriva
lblTime.Text = DateTime.Now.ToString()
i den kod som körs i egen tråd. Det kommer din applikation inte tycka om, tror att MS har lagt till ett exceptions för det i 2.0, det finns iallafall garanterat med från 3.0. Det är inte så att det inte fungerar, gör du det i 1.1/1.0 kod så fungerar det i 99,99% av alla dina tester, men när det kommer lite mer last på din applikation så kommer du upptäcka märkliga fel som du kommer ha svårt att hitta.
Så all uppdatering av kontroller i GUI måste ske i main-tråden.
Det andra problemet som är ett större problem, är att någon annan tråd kan komma in och ändra i din collection under tiden som du loopar igenom den, och detta kommer ge dig kritiska fel. Det kan även vara så att 2 trådar försöker skriva till samma minnesrymd samtidigt vilket inte kommer uppskattas av .NET och kommer ge dig konstiga exceptions som du kommer ha svårt att hitta, dessutom så kanske det lyckas, men datan blir korrupt....
BackGroundWorker thread hjälper dig att lösa problemet med att uppdatera till ditt GUI. Tyvärr hjälper den dig inte med att flera trådar försöker accessa samma data samtidigt, då måste man börja med lock och mutex, för att förhindra så att olika trådar kan accessa samma data samtidigt, och det är faktistkt betydligt mer komplicerat än man tror...
Jag har just detta problem i en WPF applikation som jag håller på med. Jag har en egen skriven collectionklas som är "binded" till en ListView och med hjälp av olika Interface och events så är det fixat så att om man ändrar i något i collection så kastar den event upp till listviewn att något är ändrat och listviewn uppdaterar sig själv. I en enkel trådad applikation är detta inga problem, och man kan använda sig av standard collection som finns med i .NET. Men så fort man uppdaterar collection från en annan tråd, så får man ett fel. Det är nu löst genom att se till så att uppdateringen sker i applikations egen tråd, där av den egenskrivna collection, för det klara ingen av MS standard kollektionern.
Då inträffar problemet om du har en tråd som lägger till objekt och en annan som tar bort objekt från collection. Innan den tråden som har lagt till objektet är riktigt färdig med alla notificeringar som den skall göra och innan listview hunnit uppdaterar sig och visa det nya objektet så har min tråd som tar bort objekt hunnit ta bort objektet från collectionen. Så när listview efterfrågar det nya objektet från collectionen för att visa det i kontrollen så finns det inte där längre och vips så har vi en exception.
Enkelt trodde jag, bara att göra lite lock på rätt ställen så löser det sig, första försöket slutade i deadlocks (alltså att 2 olika trådar står och väntar på varandra att bli färdig, eller till och med att samma tråd väntar på sig själv eftersom den råkar stötat på samma lock) efter ha hackat om lite så tycker jag att alla problem är lösta och gör en test, fungerar bra, gör lite mer testar allt fungerar bra, tills jag tryckte ner så att det skapas ett nytt objekt var 1-5 millisekund, och var 1-5 millisekund så tar man bort ett objekt och var 1-5 millisekund så uppdaterar jag ett objekt från listan. Det fungerarde bra i några tusen objekt, sedan poff... Kunde inte hitta objektet i collection.
Och jag måste säga att jag tycker att jag gjort allt rätt och kan inte se hur objektet kan bli borttaget innan alla uppdateringar är färdiga... och det suger fett. men det är iallfall ett betydligt framsteg i från första försöket (y)
- M