Úkol rozdíl mezi asynchronním a synchronním programováním
Jednoduchý úkol, který ukazuje rozdíl mezi asynchronním a synchronním programováním
3. Řešení úkolu
Třída Procesor
namespace asynchronni_synchronni_rozdil_ukol.Models { public class Procesor { public void PracujTvrde(int milisekundy) //ŠPATNĚ: Synchronní metoda, která zblokuje celé vlákno { //Thread.Sleep uspí vlákno na danou dobu. //V prohlížeči to znamená, že se přestane vykreslovat UI. System.Threading.Thread.Sleep(milisekundy); } public async Task PracujChytreAsync(int milisekundy) //SPRÁVNĚ: Asynchronní metoda, která uvolní vlákno { //Task.Delay vytvoří úkol "čekání", ale vlákno procesoru uvolní pro jinou práci. await Task.Delay(milisekundy); } } }
Třída Procesor slouží k simulaci časově náročné operace. Obsahuje dvě metody, které demonstrují rozdílný přístup k využívání procesorového času. Metoda PracujTvrde je synchronní a využívá příkaz Thread.Sleep, který zablokuje aktuální vlákno aplikace (aplikace musí čekat). Metoda PracujChytreAsync je definována jako asynchronní (klíčová slova async a Task) a využívá příkaz Task.Delay, který sice vytvoří prodlevu, ale vlákno uvolní pro jinou práci.
Razor komponenta
@page "/" <PageTitle>Test zamrznutí</PageTitle> <h1>Test: Sync vs Async</h1> <div class="row"> <div class="col-6 border p-3"> <h3>1. Simulace práce</h3> <p>Stav aplikace: <strong>@stavAplikace</strong></p> <!--Výpis stavu aplikace--> <button class="btn btn-danger mb-2" @onclick="SpustitZamrznuti"> <!--Zablokuje hlavní vlákno aplikace--> Synchronní metoda (Thread.Sleep) </button> <br /> <button class="btn btn-success" @onclick="SpustitNaPozadi"> <!--Uvolní vlákno pro další úlohy--> Asynchronní metoda (Task.Delay) </button> </div> <div class="col-6 border p-3 bg-light"> <h3>2. Test responzivity</h3> <p>Zkuste během práce klikat na toto tlačítko. Pokud to nejde, aplikace zamrzla.</p> <button class="btn btn-primary btn-lg" @onclick="ZvysitPocitadlo"> <!--Počítadlo kliknutí, můžeme ověřit zda aplikace zamrzla--> Klikni na mě! (@pocetKliknuti) </button> </div> </div> @code { private Models.Procesor procesor = new Models.Procesor(); //Instance naší třídy private string stavAplikace = "Připraveno"; private int pocetKliknuti = 0; private void ZvysitPocitadlo() //Metoda pro obyčejné počítadlo (abychom viděli, zda UI reaguje) { pocetKliknuti++; } private void SpustitZamrznuti() //SYNCHRONNÍ METODA { stavAplikace = "Aplikace ZAMRZÁ na 3 sekundy..."; //Zde voláme synchronní metodu. //Prohlížeč se na tomto řádku zastaví a neumí překreslit obrazovku ani přijmout kliknutí. //Dokonce ani text "Aplikace ZAMRZÁ" se pravděpodobně nestihne vykreslit před zaseknutím. procesor.PracujTvrde(3000); stavAplikace = "Hotovo (Už zase běžím)."; } private async Task SpustitNaPozadi() //ASYNCHRONNÍ METODA { stavAplikace = "Pracuji na pozadí (3s)..."; //Zde voláme asynchronní metodu s 'await'. //Kód čeká, ale UI vlákno je volné. Můžete klikat na počítadlo vedle. await procesor.PracujChytreAsync(3000); stavAplikace = "Hotovo (Práce dokončena)."; } }
V HTML části je stránka rozdělena na dva sloupce. Levý sloupec slouží k ovládání simulace. Pravý sloupec obsahuje testovací tlačítko s počítadlem, které slouží jako indikátor responzivity – pokud na něj během práce nelze klikat, znamená to, že uživatelské rozhraní zamrzlo.
V části @code se vytváří instance třídy Procesor. Metoda SpustitZamrznuti volá synchronní metodu PracujTvrde, což způsobí okamžité zaseknutí prohlížeče. Naopak metoda SpustitNaPozadi volá asynchronní metodu pomocí klíčového slova await, díky čemuž aplikace čeká na dokončení úlohy, ale zároveň zůstává plynulá a uživatel může dále ovládat prvky na stránce.