[C# WPF] Viac vlakien, ktore hybu obrazkom po Canvase.

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod sejnt 22. 10. 2014 22:56

Zdravim mam aplikaciu, ktora simuluje zeleznicnu dopravu. Teraz som ale narazil na problem. Uzivatel si moze nastavit pocet vlakov a aj nakreslit trasy po ktorych pojdu. No a ja teraz neviem ako mam vytvorit vlakna podla poctu vlakov, ktore sa budu po mape pohybovat po danych suradniciach. Moja predstava bola taka ze jeden vlak = jedno vlakno. Vzdy sa mi ale podarilo pohybovat jednym vlakom a az nasledne sa mi sputil druhy.

Kód: Vybrat vše
    mMyDelegateType work = delegate
                {
                    TrainMove(mMap.Tracks[0]);
                };
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, work);

                mMyDelegateType work1 = delegate
                {
                    TrainMove(mMap.Tracks[1]);
                };
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, work1);


a tu metoda, ktora vykresluje vlak:

Kód: Vybrat vše
  private async void TrainMove(List<Track> aTrack)
        {
            foreach (var nItem in aTrack)
            {
                Image lTrain = new Image
                {
                    Source = new BitmapImage(new Uri("/Resources/train.bmp", UriKind.Relative))
                };
                lTrain.Tag = "train";
                Canvas.SetLeft(lTrain, nItem.X);
                Canvas.SetTop(lTrain, nItem.Y);

                RunCanvas.Children.Add(lTrain);

                await Task.Delay(50);

                RunCanvas.Children.Remove(lTrain);

            }
        }


Skusal som to BeginInvoke davat do cyklu, Pouzit len Invoke, ale nic nepomohlo. Teraz ma napadlo, ze ci to nie je obmedzene tym ze tie vlakna citaju z jednej premenej mMap.Track.

Dakujem za rady.
Lekvár je produkt šialenej myšlienky ako neurobiť zo všetkých sliviek slivovicu.[CZ] Povidla jsou produkt šílený myšlenky jak neudelat ze všech švestek slivovici.
sejnt
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 23. 10. 2014 03:14

WPF moc neznám, ale mám jedno doporučení. Vykreslovat bude jen jedno vlákno.
Výpočet pohybu si můžeš dělat v několika vláknech jak chceš, ale pak to musíš uložit do nějaké sdílené paměti (a korektně locknout přístup) a z této paměti to pak v tom vykreslovacím vláknu přečíst (opět s korektním lockem) a zobrazit pohyb.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod johnyx 23. 10. 2014 03:27

Vidím, že používate delegáty a invoke. Nevím, jestli si to pamatuji správně, nicméně, když z threadu zavoláte invoke, spustíte danou proceduru ve vlákě hlavním, kde běží i gui. A hlavní vlákno může dělat jen jednu věc, nikoliv dvě.

Řešení může být, to co psal nargon, tedy obsáhnout pohyb všech vláku v jednom vlákně. A nebo je tu pak prasárna: Form.CheckForIllegalCrossThreadCalls= False a invoke vůbec nevolat. Ale to se vám může stát, že vám pojede jen půlka 5 vlaků. Těžko soudit...
Trance is still alive ....
johnyx
Kolemjdoucí

Odeslat příspěvekod PiranhaGreg 23. 10. 2014 04:22

Hehe, tohle jsem měl na střední asi 2 roky zpět jako závěrečnej domácí úkol :mrgreen: . Skončil jsem u řešení jak píše Nargon.
PiranhaGreg
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod Nargon 23. 10. 2014 05:38

Paralelizace je krásná věc, ale něco se fakt paralelizovat nedá. Nejlepší příkad je na práci se soubory. Když budeš chtít načíst 10 velkých souborů, každý třeba o velikosti 1GB z klasického HDD. A budeš je číst sekvenčně (tj jeden za druhým) tak to zabere nějaký čas. Když je zkusíš načítat 10ti vlákny, tak to v nejlepším případě bude stejně rychlé, ale spíš to bude celkově trvat déle, protože hlavička disku stále bude lítat mezi soubory a tím přesunem ztratí hromadu času, který by jinak mohla využít na to čtení.
U grafického výstupu asi taky bude někde v ovladačích zámek (nebo něco) co umožní aktivní přístup jen jednomu vláknu. Je to ochrana aby se nezobrazovali nějaké nenačtené hodnoty a podobně.

Pokud chceš i vícevláknové vykreslování tak nejlepší co můžeš udělat, je v těch vláknech si ten jeden snímek vykreslit do nějakého vlastního obrázku v paměti. Když to budeš dělat korektně, tak to může běžet i vícevláknově. Pak ale zase bude jen jedno vlákno, které ten obrázek zobrazí v tom okně.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod sejnt 28. 10. 2014 20:59

No, na moje prekvapenie(a mozno aj vase), moje riesenie, ktore je uplne hore je funkcne :D . Chyba bola v tom, ze ako som kreslil trat, ukladal som si dane pozicie do jedneho listu, a ten som po skonceni nezmazal, takze dalsia trat sa pridala na koniec..

//EDIT : Na simulacii samozrejme vidno ze vlaky sa nepohnu zaroven, Povodne som to chcel opravit tak ze to jedno nove vlakno by malo dve fazy v prvej by som zistil pozicie vsetkych objektov a v druhej by som to proste vykreslil. Dakujem za vas cas.:)
Lekvár je produkt šialenej myšlienky ako neurobiť zo všetkých sliviek slivovicu.[CZ] Povidla jsou produkt šílený myšlenky jak neudelat ze všech švestek slivovici.
sejnt
Junior
Uživatelský avatar

Odeslat příspěvekod Bespi_ 28. 10. 2014 22:02

Jedna drobnost mimo otazku. Zkus misto bitmap pouzivat rovnou vektorove obrazky at to casem nemusis predelavat. Uz ted plno lidi pouziva vyssi DPI a bude to akorat pribejvat. Bitmapove obrazky vypadaji v jinak ostrem prostredi hodne spatne.
Bespi_
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků