Diskuze: Dispatcher.BeginInvoke() - nekonečné volání
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 20 zpráv z 20.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj Zirko, nezacykli se to, ale zahltis frontu udalosti a WPF to neunese.
Oprava je snadna, volej dispatcher jen obcas, treba kazdych 200ms, uz to bude fungovat
Mohl by jsi mi více rozepsat problém ? Nějak tomu nerozumím
Který problém?
Čemu přesně nerozumíš? Zahlcení fronty událostí, špatné výkonnosti nebo špatnému použití lambda funkce?
Jinak pokud v C# něco děláš s pixely bitmapy a nechceš čekat věčnost, tak doporučuji nepoužívat getpixel, ale převést si to na pole a procházet pak to, je to pak mnohem (třeba i až o dva řády - 100x) rychlejší.
Např. čtení takto:
UInt32[] data = new UInt32[bmp.Size.Width * bmp.Size.Height];
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Size.Width, bmp.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
unsafe
{
fixed (UInt32* pArray = data)
{
IntPtr intPtr = new IntPtr((void*)pArray);
CopyMemory(intPtr, bd.Scan0, bmp.Size.Width * bmp.Size.Height * 4);
}
}
bmp.UnlockBits(bd);
Pixely pak máš načtené v poli data (myslím, že by neměl být problém místo UInt32 použít i Color).
A pokud používáš MSVS, tak musíš v nastavení projektu povolit unsafe code (properties projektu -> záložka Build).
V případě zájmu sem můžu odit i rychlý kód, co používám k zápisu do bitmapy.
U toho řešení ale musíš vědět, v jakém formátu je bitmapa - 32bpc, 24bpc, ...
Jj, já to používal v http://www.itnetwork.cz/…-magickeleto , kde jsme všechnu grafiku dělali v 32bpp.
Pokud by to chtěl použít na jiné bpp, musel by obrázek převádět před
tímhle kódem do 32bpp nebo upravit ten kód (osobně bych asi spíš obrázek
převáděl na 32(nebo případně 24) bpp, rozhodně je to příjemnější
než pracovat s 16bpp, kde to pak musíš ručně posouvat, aby to sedělo
Jo díky, mrknu na to. Používám to ve WP, kde není přímo metoda GetPixel / SetPixel. Musím použít WriteableBitmap a využívám k tomu ještě knihovnu pro lepší práci.
Jasně, vysvětlím to letem světem. WPF aplikace běží ve dvou vláknech:
Když napíšeš kód pro WPF aplikaci, to co znáš jako aplikační události, běží v hlavním vlákně, které má frontu událostí k vykonání. Každá událost má prioritu, podle které se zpracovávají. Mezi události patří například i zpracování komponent v aplikaci, kdy se rozmisťují kontrolní prvky a aplikuje se vizuální strom na základě logického stromu nebo stisknutí klávesy nebo události myši. Mimo to se výsledná data posílají na grafickou kartu, abys je viděl na monitoru.
Když uděláš ten svůj cyklus na obrázku 1000x1000, tak velice rychle vložíš 1000000 událostí do hlavního vlákna a aplikace přestane stíhat. Tímhle způsobem například zabráníš zpracování klávesnice, ale i vykreslování aplikace, protože nebudou připravena data!
WPF aplikace navíc pracují na 30 nebo 60 FPS, takže takhle rychlá aktualizace hodnot nemá žádný smysl - jenom nutíš procesor a gafickou kartu, aby pracovaly "naprázdno".
Doporučuji si koupit jednu z těchto knížek, před lety se mi moc osvědčily:
Druhou chybu máš v tomhle kódu:
Dispatcher.BeginInvoke(() => { tb.Text = pc.ToString(); });
Aby to fungovalo tak, jak chceš, musíš do lambda funkce vkládat pouze imutabilní hodnoty. Takhle už je to správně:
string str = pc.ToString();
Dispatcher.BeginInvoke(() => { tb.Text = str; });
Promin, rad bych to rozepsal vice, ale je toho strasne moc.
Ale ty dve knizky jsou fakt super, hlavne Essentials WPF je primo od jednoho z
autoru WPF, takze vysvetluje veci, co nikdo jiny.
V pořádku, já to myslel zcela kladně. Zaměřím se na to trošku. S WPF,
respektive s XAML aplikacemi (Windows 8, Windows Phone) pracuju už delší dobu
a doteď jsem to používal stejným způsobem. Bohužel a vlastně i
naštěstí jsem zjistil až teď, že ne vše funguje tak jak jsem si
představoval
Měl bych otázku. Ve Windows Phone není dostupná třída BitmapData, co tak čtu vše se točí okolo třídy WriteableBitmap. Mám následující kód
int[] pixels = wb.Pixels;
for (int i = 0; i < pixels.Length; i++)
{
Color c = new Color();
byte[] values = BitConverter.GetBytes(pixels[i]);
if (!BitConverter.IsLittleEndian)
Array.Reverse(values);
c.R = values[2];
c.G = values[1];
c.B = values[0];
c.A = 255;
}
Jde to nějak urychlit ? Tohle je taky pomalý. A potřebuji právě získávat pixel po pixelu - diagnostika procentuální zastoupení barev v daném obrázku.
http://www.codeproject.com/…-with-Csharp?… mrkni na tohle, nevim jestli to na WP pojede,ale na desktopu to funguje dobře
S WP jsem nikdy nedělal, takže tam to neznám.
Zkoušel bych to přes vlastnost BackBuffer, to bude nejspíš ukazatel na surová data.
A ten Backbuffer tam je?
Není těším se na
dobu ,kdy API budou už z větší z části podobné
Zobrazeno 20 zpráv z 20.