Undrar om någon har ett passande mönster för mitt lilla trådproblem? Använder mig av BackgroundWorker för att min GUI app inte skall ”sluta svara” under en tyngre läsoperation. Allt eftersom resultatet läses in uppdateras en listvy via ReportProgress/ProgressChanged. Problemet är att läsningen ibland går väldigt fort och min bakgrundsprocess ligger och trycker på GUI-processen så hårt att bl.a. en avbryt-knapp inte längre går att trycka på. Läsningen tar förmodligen mindre tid än uppdateringen av listvyn. Ett enkelt sätt att komma runt problemet vore naturligtvis att lägga in en Thread.Sleep() i loopen i DoWork metoden, men då kanske bakgrundsprocessen ibland kommer att sova i onödan. Men låt den sova i typ 100ms, det kommer ju ingen användare att lida av.. :) Tack Ola. Det är precis så jag gjort. Pragmatiskt kanske, men det känns liksom inte helt rätt. Och, 100 ms multiplicerat med ett antal tusen blir en del (varför någon skulle vilja ha så många items i en listvy kan man skanske fråga sig, men så är det i alla fall). alternativt behöver du ju inte uppdatera UIt för varenda post utan du batchar inhop N poster och lägger till alla på en gång. Lämpligt N kan bestämmas ur stetsons tabell alternativt experimentellt. Titta även på BeginUpdate()/EndUpdate() Mitt förslag Tack Simon och Oskar, Är det ok om jag sågar den totalt? :) He, he, såga på du. Jag är bara tacksam för respons. Hm. Jag har en bättre idé om du måste frysa tråden: Gör en dummy-invoke. (fönster.Invoke(new någondelegate(någonmetod));, de skickas som window messages. När de returnerar så betyder det att ett antal meddelanden har trillat igenom. Arbetstråden får inte kontrollen förrens det behövs, bättre så.Hjälp, min bakgrundsprocess är för snabb!
Sv: Hjälp, min bakgrundsprocess är för snabb!
Sv:Hjälp, min bakgrundsprocess är för snabb!
Sv: Hjälp, min bakgrundsprocess är för snabb!
Sv:Hjälp, min bakgrundsprocess är för snabb!
1) Skaffa en timer
2) Skaffa en kö a
4) Timern ska inte autoreseta
5) När workern är klar: Starta timern, om ej startad, varje gång någonting blir klart. Skaffa lämpligt lås, stoppa in i kö a vad som ska läggas till
6) När timern är körd: Skaffa lämpligt lås. "Ta" kö a (lokal variabel, skapa ny instans av kö:n i publika variabeln.) Anropa typ BeginUpdate eller vad det nu heter på listviewen. Arbeta av listan. Anropa End UpdateSv: Hjälp, min bakgrundsprocess är för snabb!
Meckade runt lite inspirerad av era förslag. Kom dock fram till en lite annorlunda lösning. Mha följande loop i min bakgrundsprocess lyckas jag hålla hyfsad speed samtidigt som GUI:et svarar:
while (!Process.GetCurrentProcess().Responding)
{
Thread.Sleep(10);
}
Det ser ut att fungera klockrent men om någon har några invändningar så dissa gärna...
Sv:Hjälp, min bakgrundsprocess är för snabb!
Att polla på det där sättet är inte bra, fler context switches. Och i andra sammanhang så skulle det t.ex. hindra processorn från att sova, vilket är energislöseri ;)
Btw, går den här snurran i tråden som arbetar? Inte kul för prestandan :/Sv: Hjälp, min bakgrundsprocess är för snabb!
Och jag hör vad du säger. Det vore naturligtvis bättre om jag kunde söva arbetstråden så länge GUI-tråden är så upptagen att GUI:et inte svarar. Jag har dock ännu inte kommit på något sätt att åstadkomma detta.
Att använda BeginUpdate/EndUpdate var heller ingen hitt. Jag vill ju att man skall kunna se att listvyn fylls och försöker man göra det i intervaller blickar kontrollen så att man riskerar ett epileptiskt anfall.
Ja, snurran går i tråden som arbetar. Och, ja, prestandan blir lidande, men applikationen upplevs som oerhört mycket snabbare (än tidigare). Frågan är hur kostsamt den där pollningen egentligen är. Jag funderar vidare :)Sv:Hjälp, min bakgrundsprocess är för snabb!