|
|
|
# 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);`
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
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:
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
|
|
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
|
|
|
|
|