Proč čekají uvnitř dítě, zavolejte vlastně čekat?

0

Otázka

Výstup pro níže uvedený kód je

A
B
C

Od root call FirstCall() není čekají, očekával bych, že Task.Delay ne vlastně počkat, protože Úkol, který je vrácen ChildCall bubliny a je nikdy nečekal.

Může mi někdo vysvětlit, proč Task.Delay je vlastně čeká, když kořen volajícího není očekávaná?

Konkrétně, když FirstCall dosáhne čekají prohlášení uvnitř (await ChildCall()) provádění způsobu je přerušeno a řízení se vrátí do Hlavní metody. Tady FirstCall není očekávaná - co brání pak jít dopředu a provádění Console.ReadLine()


        private static void Main(string[] args)
        {
            FirstCall();
            Console.ReadLine();
        }


        private static async Task FirstCall()
        {
            await ChildCall();
            Console.WriteLine("C");
        }

        private static async Task ChildCall()
        {
            Console.WriteLine("A");


            await Task.Delay(TimeSpan.FromSeconds(5));

            Console.WriteLine("B");
        }
async-await c#
2021-11-23 02:07:33
1

Nejlepší odpověď

2

Když nechcete awaitjsi i nadále jen nit.

Pokud napíšete:

    private static void Main(string[] args)
    {
        FirstCall();
        Console.WriteLine("D");
        Console.ReadLine();
    }

Výstup bude vypadat nějak takto:

D
A
B
C

nebo

A
D
B
C

Přeskakování čekají nemá zakázat další čeká. Při volání async úkol, můžete myslet na to, jak vytvořit nové Vlákno, které dělá, že je to vlastní věc. Když zavoláte await jste prostě říct, aby aktuální vlákno, nedělejte nic, dokud ten je hotovo.

Ale druhé vlákno může stále volat čekají třetí vlákno, a řekni sám await nebo počkat, až třetí vlákno je hotovo. První vlákno, ne-li očekávané, bude jen pokračovat a zavřete program, než ostatní vlákna dokončit.

Můžete to vyzkoušet tím, že odstraní Console.Readline() a místo toho napsat Main Thread Completed


EDIT: DALŠÍ

Na vaše specifické Vůbec:

Konkrétně, když FirstCall dosáhne čekají prohlášení uvnitř (čekají ChildCall()) k provádění způsobu je přerušeno a řízení se vrátí do Hlavní metody. Tady FirstCall není očekávaná - co brání pak jít dopředu a provedení Konzole.ReadLine()

Provedení metody je, NENÍ pozastavena, jak si myslel. Viz příklad níže o svůj upravený kód:

    private static void Main(string[] args)
    {
        FirstCall();
        Console.WriteLine("Main Thread Finished...");
        var word = Console.ReadLine();
        Console.WriteLine("Printed: " + word);
        Console.ReadLine();
    }

Na obrázku níže, na levé straně jsem okamžitě Napsal test. Na pravé straně čekal jsem na dítě vlákna k dokončení:

enter image description here

Takže odpověď na tvou druhou otázku:

Takže říkáte, že každé dítě metoda má své vlastní státní stroj, který je poctěn, bez ohledu na to, co jeho rodiče dělají?

Částečně...

Odpovědět správně, musíte znát rozdíl mezi Úkolem a Nit.

Úkol vs Nit

V krátké Task používá Závit Bazén a Thread používá vyhrazené Vlákno. Myslím, vyhrazené Vlákno jako výchozí sekundární Main(args) funkce. Kde jako podprocesů používá rodič-dítě-treelike strukturu (Může být špatně), jak sledovat, co závity jsou provádění.

Co to znamená prakticky

  • Oba Úkoly a Vlákna mají kompletní vnitřní stavy, které je poctěn, bez ohledu na to, co jeho rodič | s VÝJIMKOU, Kdy Rodič Úkol je splněn, všechny Děti Úkoly Stop *Ihned.
  • Úkoly mají Návratové Typy , kde, jak Závity nemám.
  • Pro program přestane - budete muset zastavit všechny závity, ale budete muset pouze zastavit rodičovský Úkol pro zastavení programu.
2021-11-23 03:50:11

Takže říkáte, že každé dítě metoda má své vlastní státní stroj, který je poctěn, bez ohledu na to, co jeho rodiče dělají? Máte nějaký materiál, se kterým můžu odkázat?
bobbyalex

Aktualizováno otázka, aby to bylo zrušeno, proč se ptám.
bobbyalex

@bobbyalex Aktualizováno Odpověď na přidání více info
MrMoonMan

V krátké Úkol používá Závit Bazén a Nit používá vyhrazené Vlákno. - Toto tvrzení je nesprávné. Provádění, jak awaitable funguje, je až metoda. Pro např: IO vázán awaitable nepoužívá závit - závit bazén nebo jinak.
bobbyalex

@mrmoon: ThreadPool je seskupování vláken, ne nit věc. Pokud zavoláte await Task.Run nebo Delegate.Invokejste dispečinku práce závitu na závit bazén. Úkoly a vlákna jsou vzájemně propojeny, ale ne tak pevně. V OP je otázka, tam je jen jeden threas
Flydog57

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................