Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Asynchronní programy můžete psát a udržovat snadněji pomocí klíčových slov Async a Await. Výsledky vás ale mohou překvapit, pokud nerozumíte tomu, jak váš program funguje. Toto téma sleduje tok řízení prostřednictvím jednoduchého asynchronního programu, který vám ukáže, kdy se ovládací prvek přesune z jedné metody do druhé a jaké informace se pokaždé přenesou.
Poznámka:
Klíčová slova Async a Await byla představena v sadě Visual Studio 2012.
Obecně lze označit metody, které obsahují asynchronní kód s modifikátorem Async . V metodě, která je označena asynchronním modifikátorem, můžete pomocí operátoru Await (Visual Basic) určit, kde metoda pozastaví čekání na dokončení volaný asynchronní proces. Další informace naleznete v tématu Asynchronní programování pomocí Async a Await (Visual Basic).
Následující příklad používá asynchronní metody ke stažení obsahu zadaného webu jako řetězec a k zobrazení délky řetězce. Příklad obsahuje následující dvě metody.
startButton_Click, která voláAccessTheWebAsynca zobrazuje výsledek.AccessTheWebAsync, který stáhne obsah webu jako řetězec a vrátí délku řetězce.AccessTheWebAsyncpoužívá asynchronní HttpClient metodu , GetStringAsync(String)ke stažení obsahu.
Číslované zobrazované čáry se zobrazují v strategických bodech programu, které vám pomůžou pochopit, jak se program spouští, a vysvětlit, co se stane v jednotlivých označených bodech. Zobrazené řádky jsou označené jako "ONE" až "SIX". Popisky představují pořadí, ve kterém program dosáhne těchto řádků kódu.
Následující kód ukazuje osnovu programu.
Class MainWindow
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click
' ONE
Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
' FOUR
Dim contentLength As Integer = Await getLengthTask
' SIX
ResultsTextBox.Text &=
vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf
End Sub
Async Function AccessTheWebAsync() As Task(Of Integer)
' TWO
Dim client As HttpClient = New HttpClient()
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://learn.microsoft.com")
' THREE
Dim urlContents As String = Await getStringTask
' FIVE
Return urlContents.Length
End Function
End Class
Každá z označených umístění, "ONE" až "SIX", zobrazí informace o aktuálním stavu programu. Vytvoří se následující výstup:
ONE: Entering startButton_Click.
Calling AccessTheWebAsync.
TWO: Entering AccessTheWebAsync.
Calling HttpClient.GetStringAsync.
THREE: Back in AccessTheWebAsync.
Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.
FOUR: Back in startButton_Click.
Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.
FIVE: Back in AccessTheWebAsync.
Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.
SIX: Back in startButton_Click.
Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.
Length of the downloaded string: 33946.
Nastavení programu
Kód, který toto téma používá, si můžete stáhnout z MSDN nebo si ho můžete sestavit sami.
Poznámka:
Pokud chcete spustit příklad, musíte mít na počítači nainstalovanou sadu Visual Studio 2012 nebo novější a rozhraní .NET Framework 4.5 nebo novější.
Stažení programu
Aplikaci pro toto téma si můžete stáhnout z ukázky Async: Tok řízení v asynchronních programech. Následující kroky vám umožní otevřít a spustit program.
Rozbalte stažený soubor a spusťte Visual Studio.
Na řádku nabídek zvolte Soubor, Otevřít, Projekt nebo Řešení.
Přejděte do složky, která obsahuje rozbalený ukázkový kód, otevřete soubor řešení (.sln) a zvolte klíč F5 pro sestavení a spuštění projektu.
Postavte si program sami
Následující projekt WPF (Windows Presentation Foundation) obsahuje příklad kódu pro toto téma.
Pokud chcete projekt spustit, proveďte následující kroky:
Spusťte Visual Studio.
Na řádku nabídek zvolte Soubor, Nový, Projekt.
Otevře se dialogové okno Nový projekt .
V podokně Nainstalované šablony zvolte Visual Basic a pak v seznamu typů projektů zvolte Aplikaci WPF .
Zadejte
AsyncTracernázev projektu a pak zvolte tlačítko OK .Nový projekt se zobrazí v Průzkumníku řešení.
V editoru Visual Studio Code zvolte kartu MainWindow.xaml .
Pokud karta není viditelná, otevřete místní nabídku pro MainWindow.xaml v Průzkumníku řešení a pak zvolte Zobrazit kód.
V zobrazení XAML MainWindow.xaml nahraďte kód následujícím kódem.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow" Title="Control Flow Trace" Height="350" Width="525"> <Grid> <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="221,10,0,0" VerticalAlignment="Top" Width="75"/> <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="510" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" d:LayoutOverrides="HorizontalMargin"/> </Grid> </Window>Jednoduché okno, které obsahuje textové pole a tlačítko se zobrazí v návrhovém zobrazení MainWindow.xaml.
Přidejte odkaz pro System.Net.Http.
V Průzkumníku řešení otevřete kontextovou nabídku pro MainWindow.xaml.vb a pak zvolte Zobrazit zdroj.
V MainWindow.xaml.vb nahraďte kód následujícím kódem.
' Add an Imports statement and a reference for System.Net.Http. Imports System.Net.Http Class MainWindow Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click ' The display lines in the example lead you through the control shifts. ResultsTextBox.Text &= "ONE: Entering StartButton_Click." & vbCrLf & " Calling AccessTheWebAsync." & vbCrLf Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync() ResultsTextBox.Text &= vbCrLf & "FOUR: Back in StartButton_Click." & vbCrLf & " Task getLengthTask is started." & vbCrLf & " About to await getLengthTask -- no caller to return to." & vbCrLf Dim contentLength As Integer = Await getLengthTask ResultsTextBox.Text &= vbCrLf & "SIX: Back in StartButton_Click." & vbCrLf & " Task getLengthTask is finished." & vbCrLf & " Result from AccessTheWebAsync is stored in contentLength." & vbCrLf & " About to display contentLength and exit." & vbCrLf ResultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength) End Sub Async Function AccessTheWebAsync() As Task(Of Integer) ResultsTextBox.Text &= vbCrLf & "TWO: Entering AccessTheWebAsync." ' Declare an HttpClient object. Dim client As HttpClient = New HttpClient() ResultsTextBox.Text &= vbCrLf & " Calling HttpClient.GetStringAsync." & vbCrLf ' GetStringAsync returns a Task(Of String). Dim getStringTask As Task(Of String) = client.GetStringAsync("https://learn.microsoft.com") ResultsTextBox.Text &= vbCrLf & "THREE: Back in AccessTheWebAsync." & vbCrLf & " Task getStringTask is started." ' AccessTheWebAsync can continue to work until getStringTask is awaited. ResultsTextBox.Text &= vbCrLf & " About to await getStringTask & return a Task(Of Integer) to StartButton_Click." & vbCrLf ' Retrieve the website contents when task is complete. Dim urlContents As String = Await getStringTask ResultsTextBox.Text &= vbCrLf & "FIVE: Back in AccessTheWebAsync." & vbCrLf & " Task getStringTask is complete." & vbCrLf & " Processing the return statement." & vbCrLf & " Exiting from AccessTheWebAsync." & vbCrLf Return urlContents.Length End Function End ClassZvolte klávesu F5, aby se program spustil, a pak zvolte tlačítko Start .
Měl by se zobrazit následující výstup:
ONE: Entering startButton_Click. Calling AccessTheWebAsync. TWO: Entering AccessTheWebAsync. Calling HttpClient.GetStringAsync. THREE: Back in AccessTheWebAsync. Task getStringTask is started. About to await getStringTask & return a Task<int> to startButton_Click. FOUR: Back in startButton_Click. Task getLengthTask is started. About to await getLengthTask -- no caller to return to. FIVE: Back in AccessTheWebAsync. Task getStringTask is complete. Processing the return statement. Exiting from AccessTheWebAsync. SIX: Back in startButton_Click. Task getLengthTask is finished. Result from AccessTheWebAsync is stored in contentLength. About to display contentLength and exit. Length of the downloaded string: 33946.
Sledování programu
Kroky 1 a DVA
První dva zobrazené řádky sledují cestu jako startButton_Click volá AccessTheWebAsync, a AccessTheWebAsync volá asynchronní metodu HttpClientGetStringAsync(String). Následující obrázek znázorňuje volání z metody do metody.
Návratový typ obou AccessTheWebAsync a client.GetStringAsync je Task<TResult>. Hodnota AccessTheWebAsyncTResult je celé číslo. Pro GetStringAsync, TResult je řetězec. Další informace o asynchronních návratových typech metod naleznete v tématu Asynchronní návratové typy (Visual Basic).
Asynchronní metoda vracející úlohu vrátí instanci úlohy, když se kontrola vrátí zpět k volajícímu. Řízení se vrátí z asynchronní metody volajícímu buď když je operátor Await nalezen v volané metodě, nebo když volaná metoda skončí. Řádky displeje, které jsou označeny jako "TŘI" až "ŠEST", zaznamenávají tuto část procesu.
Krok 3
V AccessTheWebAsync se volá asynchronní metoda GetStringAsync(String), aby stáhla obsah cílové webové stránky. Ovládání se vrátí z client.GetStringAsync do AccessTheWebAsync když se client.GetStringAsync vrátí.
Metoda client.GetStringAsync vrátí úlohu řetězce, který je přiřazen k getStringTask proměnné v AccessTheWebAsync. V následujícím řádku ukázkového programu je ukázáno volání client.GetStringAsync a přiřazení.
Dim getStringTask As Task(Of String) = client.GetStringAsync("https://learn.microsoft.com")
Úkol si můžete představit jako příslib, který client.GetStringAsync nakonec vyprodukuje skutečný řetězec. Do té doby, pokud má AccessTheWebAsync práci, která nezávisí na slibovaném řetězci od client.GetStringAsync, tato práce může pokračovat, zatímco client.GetStringAsync čeká. V příkladu následující řádky výstupu, které jsou označeny jako TŘI, představují příležitost provádět nezávislou práci.
THREE: Back in AccessTheWebAsync.
Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.
Následující příkaz pozastaví průběh v AccessTheWebAsync během čekání na getStringTask.
Dim urlContents As String = Await getStringTask
Následující obrázek znázorňuje tok řízení z client.GetStringAsync do přiřazení do getStringTask a od vytvoření getStringTask k aplikaci operátoru Await.
Výraz await pozastaví AccessTheWebAsync, dokud se client.GetStringAsync nevrátí. Mezitím se řízení vrátí volajícímu AccessTheWebAsync, startButton_Click.
Poznámka:
Obvykle očekáváte volání asynchronní metody okamžitě. Například následující přiřazení by mohlo nahradit předchozí kód, který vytváří a poté čeká getStringTask: Dim urlContents As String = Await client.GetStringAsync("https://learn.microsoft.com")
V tomto tématu se operátor await použije později k zpracování výstupních řádků, které označují proces řízení v programu.
Krok 4
Deklarovaný návratový AccessTheWebAsync typ je Task(Of Integer). Proto když je AccessTheWebAsync pozastaveno, vrátí úkol s celočíselným výsledkem do startButton_Click. Měli byste pochopit, že vrácený úkol není getStringTask. Vrácený úkol je novým úkolem typu celé číslo, který reprezentuje zbývající práci v pozastavené metodě, AccessTheWebAsync. Úkol je příslibem od AccessTheWebAsync vytvořit celé číslo, když je úkol dokončen.
Následující příkaz přiřadí tento úkol proměnné getLengthTask .
Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
Stejně jako v AccessTheWebAsync, startButton_Click může pokračovat v práci, která nezávisí na výsledcích asynchronní úlohy (getLengthTask), dokud se tato úloha nečeká. Následující výstupní řádky představují tuto práci:
FOUR: Back in startButton_Click.
Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.
Průběh startButton_Click se pozastaví, když se čeká na getLengthTask. Příkaz přiřazení pozastaví startButton_Click do doby, než bude AccessTheWebAsync dokončen.
Dim contentLength As Integer = Await getLengthTask
Na následujícím obrázku znázorňují šipky tok řízení z výrazu AccessTheWebAsync await do přiřazení hodnoty k getLengthTask, následované normálním zpracováním startButton_Click , dokud getLengthTask nebude očekáváno.
Krok PĚT
Když client.GetStringAsync signalizuje, že je dokončeno, zpracování AccessTheWebAsync se uvolní z pozastavení a může pokračovat za příkazem await. Následující řádky výstupu představují obnovení zpracování:
FIVE: Back in AccessTheWebAsync.
Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.
Operand návratového příkazu , urlContents.Lengthje uložen v úkolu, který AccessTheWebAsync vrací. Výraz await načte tuto hodnotu z getLengthTask v rámci startButton_Click.
Následující obrázek znázorňuje přenos ovládání po dokončení client.GetStringAsync (a getStringTask).
AccessTheWebAsync dokončí běh, a řízení se vrátí k startButton_Click, který čeká na dokončení.
Krok ŠEST
Když AccessTheWebAsync signalizuje, že je dokončeno, zpracování může pokračovat po příkazu await v startButton_Async. Ve skutečnosti, program nemá nic víc dělat.
Následující řádky výstupu představují obnovení zpracování v startButton_Async:
SIX: Back in startButton_Click.
Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.
Výraz await načte z getLengthTask celočíselné hodnoty, která je operandem příkazu return v AccessTheWebAsync. Následující příkaz přiřadí této hodnotě contentLength proměnné.
Dim contentLength As Integer = Await getLengthTask
Následující obrázek ukazuje návrat ovládacího prvku z AccessTheWebAsync do startButton_Click.