Cvičenie 9
Cieľom tohoto cvičenia je oboznámiť sa s paralelnou prácou viacerých vlákien. Doteraz ste vedeli programovať veci iba sekvenčne, teda po sebe. Tento prístup však nie je veľmi vhodný, najmä z užívateľského hľadiska, keď je potrebné realizovať veci, ktoré trvajú dlhšie, a teda by zablokovali užívateľské rozhranie, ktoré beží v hlavnom vlákne (slávne this program is not responding). Taktiež pri klasickom, sekvenčnom, programovaní je problém robiť rôzne časovače, čítanie zo súborov, atď. Niekoľko uvedených príkladov nám naznačuje potrebu programy paralelizovať.
V rámci dnešného cvičenia si ukážeme niekoľko nástrojov použiteľných na paralelizáciu, konkrétne Thread, async Task, BackgroundWorker. Threadpool nebudeme potrebovať, ale môžete si ho naštudovať sami.
1. Parallelisation
Vytvorte si konzolovú aplikáciu. V rámci nej si inizializujte zoznam hodnotami 0-99. Vypočítajte druhú odmocninu každého čísla a vypíšte ich (všetko vykonajte v jednom cykle, nech hodnoty v zozname zostanú nezmenené v zozname).
Zobrazili sa čísla v poradí? Prečo?
Teraz si tento kód upravte na paralelný foreach:
Parallel.ForEach(collection, lambda);
Parallel.ForEach(numbers, x =>
{
//magic with x
});
Vypísali sa teraz tieto čísla v poradí? Prečo?
2. Threads
Vlákna majú v základe 3 časti:
- Inicializácia
- Beh
- Finalizácia
Inicializácia a beh sú zvyčajne v jednej funkcií (alebo ešte lepšie inicializácia je v osobitnej funkcií a je zavolaná pri spustení vlákna). V rámci behu sa vykonáva nejaká dlhotrvajúca úloha, v našom prípade to bude odpočítavanie do výbuchu bomby:
- Nech sa v každom momente kontroluje či je stlačené nejaké tlačidlo (pomocou
Console.ReadKey()
- ak neviete ako na to, použite StackOverflow) ak je stlačené vami zvolené tlačidlo, odpočítavanie sa zastaví a vypíše sa zodpovedajúca správa, inak ak dosiahne 0 bomba vybuche, znovu vypíšte správu.
Ako na vlákna:
- alternatíva 1: https://www.tutorialspoint.com/csharp/csharp_multithreading.htm
- alternatíva 2:
Thread thread = new Thread(() =>
{
//task that takes a long time to finish
});
thread.Start();
thread.Abort()
zastaví vlákno, treba ošetriť! Ako na to máte ukázané v rámci horeuvedeného odkazu.
Túto úlohu možete riešiť jedným z uvedených spôsobov - dedenie od triedy Thread, ako je to v odkaze alebo lambda výraz
3. Background worker
Otvorte si projekt z minulého cvičenia a zabezpečte, aby sa každých X sekúnd zvýšil plat každého zamestnanca o 3% (rátajme medziročný rast mzdy) - doplňte si potrebné metódy a premenné. Využite BackgroundWorker: https://www.dotnetperls.com/backgroundworker