Sdílet prostřednictvím


Asynchronní návratové typy (Visual Basic)

Asynchronní metody mají tři možné návratové typy: Task<TResult>, Taska void. V jazyce Visual Basic je návratový typ void zapsán jako dílčí procedura. Další informace o asynchronních metodách naleznete v tématu Asynchronní programování pomocí Async a Await (Visual Basic).

Každý návratový typ je zkoumán v jedné z následujících částí a můžete najít úplný příklad, který používá všechny tři typy na konci tématu.

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ší.

Návratový typ úkolu(T)

Návratový Task<TResult> typ se používá pro asynchronní metodu , která obsahuje return příkaz, ve kterém operand má typ TResult.

V následujícím příkladu TaskOfT_MethodAsync asynchronní metoda obsahuje návratový příkaz, který vrací celé číslo. Deklarace metody proto musí určit návratový Task(Of Integer)typ .

' TASK(OF T) EXAMPLE
Async Function TaskOfT_MethodAsync() As Task(Of Integer)

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.FromResult is a placeholder for actual work that returns a string.
    Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())

    ' The method then can process the result in some way.
    Dim leisureHours As Integer
    If today.First() = "S" Then
        leisureHours = 16
    Else
        leisureHours = 5
    End If

    ' Because the return statement specifies an operand of type Integer, the
    ' method must have a return type of Task(Of Integer).
    Return leisureHours
End Function

Když TaskOfT_MethodAsync je volána z výrazu await, výraz await načte celočíselnou hodnotu (hodnotu ) leisureHoursuloženou v úkolu, který je vrácen TaskOfT_MethodAsync. Další informace o výrazech await naleznete v tématu Operátor Await.

Následující volání kódu a awaits metoda TaskOfT_MethodAsync. Výsledek se přiřadí proměnné result1 .

' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()

Můžete lépe pochopit, jak k tomu dochází, oddělením volání TaskOfT_MethodAsync od aplikace Await, jak ukazuje následující kód. Volání metody TaskOfT_MethodAsync , která není okamžitě očekávána, vrátí Task(Of Integer)hodnotu , jak byste očekávali od deklarace metody. Úkol je přiřazen k integerTask proměnné v příkladu. Protože integerTask je , Task<TResult>obsahuje Result vlastnost typu TResult. V tomto případě TResult představuje celočíselné typy. Při Await použití na integerTaskvýraz await vyhodnotí obsah Result vlastnosti integerTask. Tato hodnota je přiřazena result2 proměnné.

Upozorňující

Vlastnost Result je blokující vlastnost. Pokud se ho pokusíte získat přístup před dokončením jeho úkolu, vlákno, které je aktuálně aktivní, se zablokuje, dokud se úkol nedokončí a hodnota bude k dispozici. Ve většině případů byste k hodnotě měli přistupovat místo Await přímého přístupu k vlastnosti.

' Call and await in separate statements.
Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()

' You can do other work that does not rely on resultTask before awaiting.
textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf

Dim result2 As Integer = Await integerTask

Příkazy display v následujícím kódu ověřují, že hodnoty result1 proměnné, result2 proměnné a Result vlastnosti jsou stejné. Mějte na Result paměti, že vlastnost je blokující vlastnost a neměla by být přístupná, než bude jeho úkol očekáván.

' Display the values of the result1 variable, the result2 variable, and
' the resultTask.Result property.
textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf

Návratový typ úkolu

Asynchronní metody, které neobsahují návratový příkaz nebo obsahují návratový příkaz, který nevrací operand, obvykle mají návratový Tasktyp . Tyto metody by byly dílčí postupy, pokud by byly zapsány tak, aby běžely synchronně. Pokud použijete návratový Task typ pro asynchronní metodu, volající metoda může pomocí Await operátoru pozastavit dokončení volajícího, dokud se zavolá asynchronní metoda nedokončí.

V následujícím příkladu asynchronní metoda Task_MethodAsync neobsahuje návratový příkaz. Proto zadáte návratový Task typ pro metodu, která umožňuje Task_MethodAsync být očekávána. Definice Task typu neobsahuje Result vlastnost pro uložení návratové hodnoty.

' TASK EXAMPLE
Async Function Task_MethodAsync() As Task

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.Delay is a placeholder for actual work.
    Await Task.Delay(2000)
    textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf

    ' This method has no return statement, so its return type is Task.
End Function

Task_MethodAsync je volána a očekávána pomocí příkazu await místo výrazu await, podobně jako volání příkazu synchronní Sub nebo void-returning metoda. Aplikace operátoru Await v tomto případě negeneruje hodnotu.

Následující volání kódu a awaits metoda Task_MethodAsync.

' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()

Stejně jako v předchozím Task<TResult> příkladu můžete volání Task_MethodAsync oddělit od aplikace Await operátoru, jak ukazuje následující kód. Mějte však na paměti, že Task vlastnost nemá Result a že se při použití operátoru Taskawait na operátoru operátoru await negeneruje žádná hodnota .

Následující kód odděluje volání Task_MethodAsync od čekání na úkol, který Task_MethodAsync se vrátí.

' Call and await in separate statements.
Dim simpleTask As Task = Task_MethodAsync()

' You can do other work that does not rely on simpleTask before awaiting.
textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf

Await simpleTask

Návratový typ Void

Primární použití Sub procedur je v obslužných rutinách událostí, kde neexistuje žádný návratový typ (označovaný jako návratový typ void v jiných jazycích). Návrat void lze také použít k přepsání metod vrácení void nebo pro metody, které provádějí aktivity, které mohou být kategorizovány jako "fire and forget". Měli byste však vrátit Task kdykoli je to možné, protože asynchronní metoda void-return není možné očekávat. Každý volající takové metody musí být schopen pokračovat v dokončení, aniž by čekal na dokončení volanou asynchronní metodu a volající musí být nezávislý na všech hodnotách nebo výjimkách, které asynchronní metoda generuje.

Volající asynchronní metody void-return nemůže zachytit výjimky, které jsou vyvolány z metody, a takové neošetřené výjimky pravděpodobně způsobí selhání vaší aplikace. Pokud dojde k výjimce v asynchronní metodě, která vrací Task výjimku nebo Task<TResult>, je výjimka uložena ve vrácené úloze a rethrown, když je úkol očekáván. Proto se ujistěte, že všechny asynchronní metody, které mohou vyvolat výjimku, mají návratový Task typ nebo Task<TResult> že volání metody jsou očekávána.

Další informace o tom, jak zachytit výjimky v asynchronních metodách, naleznete v tématu Try... Chytit... Příkaz Finally.

Následující kód definuje asynchronní obslužnou rutinu události.

' SUB EXAMPLE
Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click

    textBox1.Clear()

    ' Start the process and await its completion. DriverAsync is a
    ' Task-returning async method.
    Await DriverAsync()

    ' Say goodbye.
    textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
End Sub

Kompletní příklad

Následující projekt WPF (Windows Presentation Foundation) obsahuje příklady kódu z tohoto tématu.

Pokud chcete projekt spustit, proveďte následující kroky:

  1. Spusťte Visual Studio.

  2. Na řádku nabídek zvolte Soubor, Nový, Projekt.

    Otevře se dialogové okno Nový projekt .

  3. V kategorii Nainstalované šablonyzvolte Visual Basic a pak zvolte Windows. V seznamu typů projektů zvolte aplikaci WPF.

  4. Zadejte AsyncReturnTypes název projektu a pak zvolte tlačítko OK .

    Nový projekt se zobrazí v Průzkumník řešení.

  5. 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ík řešení a pak zvolte Otevřít.

  6. V okně XAML MainWindow.xaml nahraďte kód následujícím kódem.

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button x:Name="button1" Content="Start" HorizontalAlignment="Left" Margin="214,28,0,0" VerticalAlignment="Top" Width="75" HorizontalContentAlignment="Center" FontWeight="Bold" FontFamily="Aharoni" Click="button1_Click"/>
            <TextBox x:Name="textBox1" Margin="0,80,0,0" TextWrapping="Wrap" FontFamily="Lucida Console"/>
    
        </Grid>
    </Window>
    

    V okně Návrh souboru MainWindow.xaml se zobrazí jednoduché okno obsahující textové pole a tlačítko.

  7. V Průzkumník řešení otevřete místní nabídku pro MainWindow.xaml.vb a pak zvolte Zobrazit kód.

  8. Nahraďte kód v MainWindow.xaml.vb následujícím kódem.

    Class MainWindow
    
        ' SUB EXAMPLE
        Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click
    
            textBox1.Clear()
    
            ' Start the process and await its completion. DriverAsync is a
            ' Task-returning async method.
            Await DriverAsync()
    
            ' Say goodbye.
            textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
        End Sub
    
        Async Function DriverAsync() As Task
    
            ' Task(Of T)
            ' Call and await the Task(Of T)-returning async method in the same statement.
            Dim result1 As Integer = Await TaskOfT_MethodAsync()
    
            ' Call and await in separate statements.
            Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()
    
            ' You can do other work that does not rely on resultTask before awaiting.
            textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf
    
            Dim result2 As Integer = Await integerTask
    
            ' Display the values of the result1 variable, the result2 variable, and
            ' the resultTask.Result property.
            textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
            textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
            textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf
    
            ' Task
            ' Call and await the Task-returning async method in the same statement.
            Await Task_MethodAsync()
    
            ' Call and await in separate statements.
            Dim simpleTask As Task = Task_MethodAsync()
    
            ' You can do other work that does not rely on simpleTask before awaiting.
            textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf
    
            Await simpleTask
        End Function
    
        ' TASK(OF T) EXAMPLE
        Async Function TaskOfT_MethodAsync() As Task(Of Integer)
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.FromResult is a placeholder for actual work that returns a string.
            Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())
    
            ' The method then can process the result in some way.
            Dim leisureHours As Integer
            If today.First() = "S" Then
                leisureHours = 16
            Else
                leisureHours = 5
            End If
    
            ' Because the return statement specifies an operand of type Integer, the
            ' method must have a return type of Task(Of Integer).
            Return leisureHours
        End Function
    
        ' TASK EXAMPLE
        Async Function Task_MethodAsync() As Task
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.Delay is a placeholder for actual work.
            Await Task.Delay(2000)
            textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf
    
            ' This method has no return statement, so its return type is Task.
        End Function
    
    End Class
    
  9. Zvolte klávesu F5, aby se program spustil, a pak zvolte tlačítko Start .

    Měl by se zobrazit následující výstup:

    Application can continue working while the Task<T> runs. . . .
    
    Value of result1 variable:   5
    Value of result2 variable:   5
    Value of integerTask.Result: 5
    
    Sorry for the delay. . . .
    
    Application can continue working while the Task runs. . . .
    
    Sorry for the delay. . . .
    
    All done, exiting button-click event handler.
    

Viz také