Ahoj, zajimalo by me reseni nasledujiciho problemu:
Mam jednoduchy formular se dvema prvky button a listView. Po kliknuti na button se spusti funkce s cyklem treba 10 smycek, ktera plni listView stringy treba "Ahoj 1", "Ahoj 2" atd. Tak a chtel bych aby po kazde smycce cyklu byla ihhed videt aktualizace obsahu toho listView. Zatim se mi to aktualizuje az po skonceni cele funkce, behem jejiho provadeni je formular "jakoby zamrzly". Nevite jak na to?
Fórum › .NET
Aktualizace listView
To zamrznutí je kvůli tomu, že vypisování provádíš na primárním vlákně - to vlákno pak už nemá čas na nic jiného, ani na "ovládání" formuláře, proto se jeví jako zamrzlý. Když navíc přistupuješ z toho nového vlákna k ovládacímu prvku, tak nestačí jen tu metodu spustit asynchronně, ale navíc jí musíš "povolit" přístup k formuláři pomocí Control.Invoke nebo BackgroundWorkeru (ten je podle mě jednodušší). Podívej se na zdejší seriál o vláknech, konkrétně na tenhle díl http://programujte.com/index.php?akce=clanek&cl=2008091400-vlakna-v-c#-7-dil
To Chrasty :
No z toho moc chytrej nejsem. Precetl jsem ten clanek (prochazel jsem ty clanky o vlaknech take drive), ale stale to neni to prave a nemohu to rozlousknout.
dost toho udela Visual Studio za me, tak vykopiruji jen neco
nadefinuji BackgroundWorker
private System.ComponentModel.BackgroundWorker bw;
po kliknuti na button:
private void button1_Click(object sender, EventArgs e)
{
bw.DoWork += bw_DoWork;
bw.RunWorkerAsync();
}
nevim kde spoustet tuhle metodu:
private void NastavListView()
{
listView1.Items.Add("ahoj 1");
listView1.Items.Add("ahoj 2");
}
v metode:
private void bw_DoWork(object sender, DoWorkEventArgs e)
to vyhazuje chybu a v metode:
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
muzu sice k tem prvkum pristoupit, ale formular je stale zamrzly.
Asi jsem uplne mimo co? Stravil jsem tim dnes snad pul dne a hledal i ruzne na netu, ale stejne jsem vetsinou narazil na ruzne konzolove aplikace a moc jsem toho nepochytil...
Ok, trochu si to rozebereme.
Tenhle řádek
bw.DoWork += bw_DoWork;
zaregistruje metodu bw_DoWork události DoWork, která se vyvolá, když zavoláš RunWorkerAsync. Místo bw_DoWork můžeš tedy s klidem zaregistrovat tu svou metodu NastavListView s odpovídajícími parametry:
private void NastavListView(object sender, DoWorkEventArgs e)
{
listView1.Items.Add("ahoj 1");
listView1.Items.Add("ahoj 2");
}
A teď to chybové místo - nezavolal jsi konstruktor BackgroundWorkeru.
//málo
private System.ComponentModel.BackgroundWorker bw;
//takhle je to ok
private System.ComponentModel.BackgroundWorker bw = new BackgroundWorker;
Při spuštění aplikace pak na tebe nejspíš Visual Studio zakřičí, že přistupuješ k ovládacím prvkům z jiného vlákna, pokud spustíš normálně zkompilovaný .exe, všechno půjde jak má. Pokud bys chtěl zakázat upozorňování na cross-thread operace, můžeš takhle
Control.CheckForIllegalCrossThreadCalls = false;
To Chrasty :
Jses fakt kouzelnik. Nejsem az takovej vul, ten konstruktor jsem samozrejme zavolal, jen jsem to nevykopiroval z toho projektu cele, ale jen utrzky. Ale pri debugu na me vzdycky stekla ta hlaska cross-thread a ja myslel ze jsem zase mimo :)
Jen mam jeste dotazek. Jak je to z debugem? Kdyz to zkousim, a hodim si breakpoint treba do te funkce NastavListView presne na tuto radku listView1.Items.Add("ahoj 2"); - tak na chvilku ve formulari skoci spravne ten text a pak se formular opet jako by "uzamkne x zamrzne" a prijde mi ze trochu i prestava reagovat Visual Studio? Tohle chovani je zpusobeno vlakny?
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
ListView aktualizace obsahu — založil hráč
ListView — založil curro70
WPF listview — založil David Roško
Moderátoři diskuze