3. Řešení

Třída Objednávka

namespace asynchronni_programovani_ukol.Models
{
    public class Objednavka //Třída Objednávka, která má vlastnosti NazevPizzy a Stav
    {
        public string NazevPizzy { get; set; } = ""; 
        public string Stav { get; set; } = "Čeká ve frontě";
    }
}

Třída Objednavka slouží k evidenci toho, co se v naší kuchyni děje. Má vlastnost Stav, která se bude v čase měnit, aniž bychom museli vytvářet novou instanci objektu.


Razor komponenta

@page "/"
 
<PageTitle>Pizzerie Async</PageTitle>
 
<h1>Pizzerie U C#</h1>
 
<p>Objednejte si více pizz najednou. Díky asynchronnímu kódu se při objednání více pizz najednou aplikace nezasekne.</p>
 
<div class="mb-3">
    <button class="btn btn-primary" @onclick='() => ZpracovatObjednavku("Šunková", 3000)'>  <!--Tlačíko zavolá metodu ZpracovatObjednavku() s parametry: název pizzy a doba pečení-->
        Objednat Šunkovou (3s)
    </button>
 
    <button class="btn btn-warning" @onclick='() => ZpracovatObjednavku("Sýrová", 5000)'>
        Objednat Sýrová (5s)
    </button>
 
    <button class="btn btn-danger" @onclick='() => ZpracovatObjednavku("Pálivá", 2000)'>
        Objednat Pálivá (2s)
    </button>
</div>
 
<hr />
 
<h3>Stav objednávek:</h3>
 
<table class="table">   <!--Tabulka pro výpis objednávek-->
    <thead>
        <tr>
            <th>Pizza</th>
            <th>Aktuální stav</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var pizza in seznamObjednavek)    //Výpis objednávek a jejich stavu
        {
            <tr>
                <td>@pizza.NazevPizzy</td>
                <td>
                    @if (pizza.Stav == "Hotovo!")   //Pokud je pizza hotová, text se zbarví zeleně
                    {
                        <span class="text-success fw-bold">@pizza.Stav</span>
                    }
                    else
                    {
                        <span class="text-muted">@pizza.Stav...</span>
                    }
                </td>
            </tr>
        }
    </tbody>
</table>
 
@code {
    private List<Models.Objednavka> seznamObjednavek = new List<Models.Objednavka>();   //Vytvoření seznamu, kam budeme ukládat všechny objednávky
   
    private async Task ZpracovatObjednavku(string nazev, int dobaPeceni)    //Metoda je 'async', protože uvnitř používáme 'await'
    {
        var novaPizza = new Models.Objednavka { NazevPizzy = nazev, Stav = "Příprava těsta" };  //Vytvoření nové objednávky
       
        seznamObjednavek.Add(novaPizza); //Přidání objednávky do seznamu, aby ji mohl uživatel vidět
 
        await Task.Delay(2000); //Task.Delay() simuluje dobu přípravy těsta
 
        novaPizza.Stav = "Peče se v peci";  //Změna stavu na pečení, Task.Delay() simuluje dobu pečení
        StateHasChanged();
        await Task.Delay(dobaPeceni);
 
        novaPizza.Stav = "Hotovo!"; //Po uplynutí doby pečení se stav změní na Hotovo
    }
}

V části @code definujeme asynchronní metodu ZpracovatObjednavku. Klíčovým momentem je řádek await Task.Delay(dobaPeceni). Kdybychom zde nepoužili await (nebo použili příkaz Thread.Sleep), tlačítko by po kliknutí zůstalo "zamáčknuté" a celá stránka by zamrzla na 3 až 5 sekund. Uživatel by nemohl objednat další pizzu, dokud se ta první nedopeče. Díky asynchronnímu přístupu ale metoda pouze "odstartuje" pečení na pozadí a okamžitě uvolní aplikaci. Uživatel tak může naklikat třeba 5 pizz naráz a v tabulce uvidí, jak se každá z nich peče svým vlastním tempem a postupně se mění na "Hotovo".