Async Return Types (Visual Basic)

Async-metoder har tre möjliga returtyper: Task<TResult>, Taskoch void. I Visual Basic skrivs returtypen void som en underprocedur . Mer information om asynkrona metoder finns i Asynkron programmering med Async och Await (Visual Basic).

Varje returtyp granskas i något av följande avsnitt och du hittar ett fullständigt exempel som använder alla tre typerna i slutet av ämnet.

Kommentar

Om du vill köra exemplet måste du ha Visual Studio 2012 eller senare och .NET Framework 4.5 eller senare installerat på datorn.

Returtyp för uppgift(T)

Returtypen Task<TResult> används för en asynkron metod som innehåller en Retur-instruktion där operanden har typen TResult.

I följande exempel TaskOfT_MethodAsync innehåller metoden async en retursats som returnerar ett heltal. Därför måste metoddeklarationen ange en returtyp för Task(Of Integer).

' 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

När TaskOfT_MethodAsync anropas inifrån ett await-uttryck hämtar await-uttrycket heltalsvärdet (värdet leisureHoursför ) som lagras i aktiviteten som returneras av TaskOfT_MethodAsync. Mer information om inväntningsuttryck finns i Await Operator (Vänta operator).

Följande kod anropar och väntar på -metoden TaskOfT_MethodAsync. Resultatet tilldelas variabeln result1 .

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

Du kan bättre förstå hur detta sker genom att separera anropet till TaskOfT_MethodAsync från programmet Awaitför , som följande kod visar. Ett anrop till en metod TaskOfT_MethodAsync som inte väntar omedelbart returnerar en Task(Of Integer), som du kan förvänta dig av metodens deklaration. Uppgiften tilldelas variabeln integerTask i exemplet. Eftersom integerTask är en Task<TResult>innehåller den en Result egenskap av typen TResult. I det här fallet representerar TResult en heltalstyp. När Await tillämpas på integerTaskutvärderas await-uttrycket till innehållet i Result egenskapen integerTaskför . Värdet tilldelas variabeln result2 .

Varning

Egenskapen Result är en blockerande egenskap. Om du försöker komma åt den innan uppgiften är klar blockeras tråden som är aktiv tills aktiviteten har slutförts och värdet är tillgängligt. I de flesta fall bör du komma åt värdet genom att använda Await i stället för att komma åt egenskapen direkt.

' 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

Visningsinstruktionerna i följande kod kontrollerar att värdena för variabeln result1 , variabeln result2 och Result egenskapen är desamma. Kom ihåg att egenskapen Result är en blockerande egenskap och inte bör nås innan uppgiften har inväntats.

' 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

Typ av aktivitetsretur

Asynkrona metoder som inte innehåller en retursats eller som innehåller en retursats som inte returnerar en operand har vanligtvis en returtyp av Task. Sådana metoder skulle vara underprocedurer om de skrevs för att köras synkront. Om du använder en Task returtyp för en asynkron metod kan en anropande metod använda en Await operator för att pausa uppringarens slutförande tills den anropade asynkronmetoden har slutförts.

I följande exempel innehåller asynkron metod Task_MethodAsync inte någon retursats. Därför anger du en returtyp Task för metoden som gör det möjligt Task_MethodAsync att vänta. Definitionen av Task typen innehåller inte en Result egenskap som lagrar ett returvärde.

' 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 anropas och väntar med hjälp av en await-instruktion i stället för ett inväntningsuttryck, liknande anropsuttrycket för en synkron Sub eller void-returning-metod. Tillämpningen av en Await operator i det här fallet genererar inte något värde.

Följande kod anropar och väntar på -metoden Task_MethodAsync.

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

Precis som i föregående Task<TResult> exempel kan du separera anropet till Task_MethodAsync från en operators Await program, som följande kod visar. Kom dock ihåg att en Task inte har en Result egenskap och att inget värde skapas när en inväntningsoperator tillämpas på en Task.

Följande kod skiljer anrop Task_MethodAsync från att vänta på den uppgift som Task_MethodAsync returneras.

' 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

Returtyp för tomrum

Den primära användningen av Sub procedurer är i händelsehanterare, där det inte finns någon returtyp (kallas för en ogiltig returtyp på andra språk). En ogiltig retur kan också användas för att åsidosätta metoder som returnerar tomrum eller för metoder som utför aktiviteter som kan kategoriseras som "eld och glöm". Du bör dock returnera en Task när det är möjligt eftersom det inte går att vänta på en asynkron metod som returneras. Alla anropare av en sådan metod måste kunna fortsätta att slutföras utan att vänta på att den anropade async-metoden ska slutföras, och anroparen måste vara oberoende av alla värden eller undantag som async-metoden genererar.

Anroparen för en asynkron asynkron metod som returneras utan tomrum kan inte fånga undantag som genereras från metoden, och sådana ohanterade undantag kommer sannolikt att orsaka att programmet misslyckas. Om ett undantag inträffar i en asynkron metod som returnerar en Task eller Task<TResult>lagras undantaget i den returnerade aktiviteten och återställs när aktiviteten väntar. Kontrollera därför att alla asynkrona metoder som kan skapa ett undantag har en returtyp av Task eller Task<TResult> och att anrop till metoden väntar.

Mer information om hur du fångar undantag i asynkrona metoder finns i Prova... Fånga... Slutligen -instruktion.

Följande kod definierar en asynkron händelsehanterare.

' 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

Fullständigt exempel

Följande WPF-projekt (Windows Presentation Foundation) innehåller kodexemplen från det här avsnittet.

Utför följande steg för att köra projektet:

  1. Starta Visual Studio.

  2. På menyraden väljer du Arkiv, Nytt, Projekt.

    Dialogrutan Nytt projekt öppnas.

  3. I kategorin Installerade mallarväljer du Visual Basic och sedan Windows. Välj WPF-program i listan över projekttyper.

  4. Ange AsyncReturnTypes som namnet på projektet och välj sedan ok-knappen .

    Det nya projektet visas i Solution Explorer.

  5. I Visual Studio Code-redigeraren väljer du fliken MainWindow.xaml .

    Om fliken inte visas öppnar du snabbmenyn för MainWindow.xaml i Solution Explorer och väljer sedan Öppna.

  6. I XAML-fönstret i MainWindow.xaml ersätter du koden med följande kod.

    <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>
    

    Ett enkelt fönster som innehåller en textruta och en knapp visas i designfönstret i MainWindow.xaml.

  7. Öppna snabbmenyn för MainWindow.xaml.vb i Solution Explorer och välj sedan Visa kod.

  8. Ersätt koden i MainWindow.xaml.vb med följande kod.

    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. Välj F5-tangenten för att köra programmet och välj sedan knappen Start .

    Följande utdata bör visas:

    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.
    

Se även