Nejčastěji odpovídající uživatel
vlákna - nefunkční refresh

Dotaz
-
private void btnSta_Click(object sender, EventArgs e) { Thread dolu = new Thread(posunDolu); Refresh(); strany.Start(); dolu.Start(); } static void posunDolu() { while (y != 500) { Thread.Sleep(1000); y += 100; Refresh(); } }
_ Dobrý den jsem začátečník a mám problém s refreshováním tvořím hru tetris a vytvořil jsem si vlákno posunDolu mělo ždy posunout kostku o 100y po 1000ms ale jakmile kod dojde k Refresh ve vláknu posunDolu vypíše mi to chybu a program zamrzne. V primárním vláknš mi jde refresh normálně děkuji za radu už dlouho pátrám po internetu.
Odpovědi
-
Ahoj, pravděpodobně půjde o problém v tom, že v jednom vláknu (hlavní program) vytvoříš nějaké GUI ovládací prvky (obrázek, tlačítko,..) Tyhle ovládací prvky potom chceš měnit (např. překreslovat, měnit polohu) v jiném vláknu. To nemůžeš udělat, protože hlavní (GUI) thread obsluhuje smyčku zpráv pro GUI prvky, která řídí kreslení prvků a nedovolí ti je měnit z jiného vlákna.
Naštěstí se to dá ale vyřešit tak, že operaci změny prvku zavoláš "na GUI vlákně" i z jiného než GUI vlákna. To se dá udělat hrozně jednoduše, na začátek své metody Refresh přidej:
private void RefreshGUI() { if (pictureBox1.InvokeRequired) { pictureBox1.Invoke(new MethodInvoker(delegate() { RefreshGUI(); })); return; } // :: pokracovani metody, }
MSDN
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke.aspx
M- Označen jako odpověď Robert HakenMVP, Moderator úterý 21. července 2009 7:25
Všechny reakce
-
Ahoj, pravděpodobně půjde o problém v tom, že v jednom vláknu (hlavní program) vytvoříš nějaké GUI ovládací prvky (obrázek, tlačítko,..) Tyhle ovládací prvky potom chceš měnit (např. překreslovat, měnit polohu) v jiném vláknu. To nemůžeš udělat, protože hlavní (GUI) thread obsluhuje smyčku zpráv pro GUI prvky, která řídí kreslení prvků a nedovolí ti je měnit z jiného vlákna.
Naštěstí se to dá ale vyřešit tak, že operaci změny prvku zavoláš "na GUI vlákně" i z jiného než GUI vlákna. To se dá udělat hrozně jednoduše, na začátek své metody Refresh přidej:
private void RefreshGUI() { if (pictureBox1.InvokeRequired) { pictureBox1.Invoke(new MethodInvoker(delegate() { RefreshGUI(); })); return; } // :: pokracovani metody, }
MSDN
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke.aspx
M- Označen jako odpověď Robert HakenMVP, Moderator úterý 21. července 2009 7:25
-