Udostępnij za pośrednictwem


Typy zwrotu Async (C# i Visual Basic)

Metody komunikacji asynchronicznej mają trzy możliwe zwracanych typów: Task<TResult>, Taskoraz void.W języku Visual Basic, zwrócony typ void jest zapisany jako Sub procedury.Aby uzyskać więcej informacji na temat metod komunikacji asynchronicznej, zobacz Asynchroniczne programowania przy użyciu asynchronicznej i poczekać (C# i Visual Basic).

Każdy typ zwracany jest badany w jednej z następujących sekcji, a można znaleźć pełny przykład, w którym użyto wszystkich trzech typów na końcu tematu.

[!UWAGA]

Aby uruchomić przykład, musisz mieć program Visual Studio 2012 r., programu Visual Studio Express 2012 dla pulpitu systemu Windows, lub 4.5.NET Framework zainstalowana na komputerze.

Ten temat zawiera następujące sekcje.

  • Zwracany typ Task(T)
  • Zwracany typ zadania
  • Zwrócony typ void
  • Kompletny przykład
  • Tematy pokrewne

Zwracany typ Task(T)

Task<TResult> Zwraca typ jest używany przez metodę komunikacji asynchronicznej, który zawiera Powrót (Visual Basic) lub zwrotu instrukcji (C#), w którym operand ma typ TResult.

W poniższym przykładzie TaskOfT_MethodAsync metody asynchronicznej zawiera instrukcję return, która zwraca liczbę całkowitą.W związku z tym, deklaracja metody należy określić typ zwracany z Task(Of Integer) w języku Visual Basic lub Task<int> w języku C#.

' 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<T> EXAMPLE
async Task<int> TaskOfT_MethodAsync()
{
    // The body of the method is expected to contain an awaited asynchronous
    // call.
    // Task.FromResult is a placeholder for actual work that returns a string.
    var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());

    // The method then can process the result in some way.
    int leisureHours;
    if (today.First() == 'S')
        leisureHours = 16;
    else
        leisureHours = 5;

    // Because the return statement specifies an operand of type int, the
    // method must have a return type of Task<int>.
    return leisureHours;
}

Gdy TaskOfT_MethodAsync nazywa się od w wyrażeniu oczekiwać wyrażenie oczekiwać pobiera wartość całkowitą (wartość leisureHours) przechowywanej w zadaniu, który jest zwracany przez TaskOfT_MethodAsync.Aby uzyskać więcej informacji na temat czekają na wyrażenia, zobacz Poczekać operatora (Visual Basic) lub poczekać (C# odniesienia).

Poniższy kod wywołuje i czeka na metody TaskOfT_MethodAsync.Wynik jest przypisany do result1 zmiennej.

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

Można lepiej zrozumieć, jak się to poprzez oddzielenie wywołanie TaskOfT_MethodAsync ze stosowania Await lub await, jak w poniższym kodzie pokazano.Wywołanie metody TaskOfT_MethodAsync nie jest to oczekiwana natychmiast zwraca Task(Of Integer) lub Task<int>, jak można oczekiwać od deklaracji metody.Zadanie jest przydzielone do integerTask zmiennej w przykładzie.Ponieważ integerTask jest Task<TResult>, zawiera on Result właściwość typu TResult.W takim przypadku TResult reprezentuje typu Liczba całkowita.Gdy Await lub await jest stosowany do integerTask, oczekiwać wyrażenie ma zawartość Result właściwość integerTask.Wartość jest przypisywana do result2 zmiennej.

Informacje dotyczące przestrogiPrzestroga

Result Jest własnością blokującym.Podczas próby do niego dostęp, przed zakończeniem swojego zadania, wątek, który jest obecnie aktywny jest blokowany aż zakończeniu zadania, a wartość jest dostępna.W większości przypadków należy uzyskać dostęp do wartości, przy użyciu Await lub await zamiast bezpośrednio dostęp do właściwości.

' 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 &= String.Format("Application can continue working while the Task(Of T) runs. . . . " & vbCrLf)

Dim result2 As Integer = Await integerTask
// Call and await in separate statements.
Task<int> integerTask = TaskOfT_MethodAsync();

// You can do other work that does not rely on integerTask before awaiting.
textBox1.Text += String.Format("Application can continue working while the Task<T> runs. . . . \r\n");

int result2 = await integerTask;

Instrukcje wyświetlania poniższy kod, należy sprawdzić, czy wartości result1 zmiennej, result2 zmienną oraz Result właściwość są takie same.Należy pamiętać, że Result właściwość jest właściwością blokowania i nie powinien być dostępny, aby oczekiwały swojego zadania.

' Display the values of the result1 variable, the result2 variable, and
' the resultTask.Result property.
textBox1.Text &= String.Format(vbCrLf & "Value of result1 variable:   {0}" & vbCrLf, result1)
textBox1.Text &= String.Format("Value of result2 variable:   {0}" & vbCrLf, result2)
textBox1.Text &= String.Format("Value of resultTask.Result:  {0}" & vbCrLf, integerTask.Result)
// Display the values of the result1 variable, the result2 variable, and
// the integerTask.Result property.
textBox1.Text += String.Format("\r\nValue of result1 variable:   {0}\r\n", result1);
textBox1.Text += String.Format("Value of result2 variable:   {0}\r\n", result2);
textBox1.Text += String.Format("Value of integerTask.Result: {0}\r\n", integerTask.Result);

Zwracany typ zadania

Metody komunikacji asynchronicznej, która nie zawiera instrukcję return, lub które zawierają instrukcję return, która nie zwraca argument zazwyczaj zawierać typu zwracanego z Task.Takie metody są nieważne przywrócenie metody (Sub w języku Visual Basic), jeśli zostały napisane aby były uruchamiane synchronicznie.Klienci korzystający z Task typ zwracany przez metodę komunikacji asynchronicznej, wywołanie metody można użyć operatora oczekiwać o zawieszeniu zakończenia obiektu wywołującego, dopóki nie zakończy metody o nazwie asynchronicznej.

W poniższym przykładzie metody asynchronicznej Task_MethodAsync nie zawiera instrukcję return.W związku z tym, określ typ zwracany z Task dla metody, co umożliwia Task_MethodAsync do być oczekiwany.Definicja Task nie zawiera typu Result właściwość do przechowywania wartości zwracanej.

' 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 &= String.Format(vbCrLf & "Sorry for the delay. . . ." & vbCrLf)

    ' This method has no return statement, so its return type is Task. 
End Function
// TASK EXAMPLE
async Task Task_MethodAsync()
{
    // 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);
    // Task.Delay delays the following line by two seconds.
    textBox1.Text += String.Format("\r\nSorry for the delay. . . .\r\n");

    // This method has no return statement, so its return type is Task.  
}

Task_MethodAsyncjest nazywane i oczekiwany przy użyciu instrukcji oczekiwać zamiast wyrażenia oczekiwać, podobnego do deklaracji wywołania synchronicznego Sub lub metody zwracającej void.W tym przypadku zastosowania operatora oczekiwać nie mieć wartooć.

Poniższy kod wywołuje i czeka na metody Task_MethodAsync.

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

Tak jak w poprzednim Task<TResult> przykład, można je oddzielić wywołanie Task_MethodAsync z zastosowania operatora oczekiwać jako poniższy kod pokazuje.Jednak należy pamiętać, że Task nie ma Result właściwość i że wartość nie jest produkowany, gdy operator oczekiwać jest stosowany do Task.

Poniższy kod oddziela telefonicznej Task_MethodAsync z Oczekujące na zadanie, Task_MethodAsync zwraca.

' 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 &= String.Format(vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf)

Await simpleTask
// Call and await in separate statements.
Task simpleTask = Task_MethodAsync();

// You can do other work that does not rely on simpleTask before awaiting.
textBox1.Text += String.Format("\r\nApplication can continue working while the Task runs. . . .\r\n");

await simpleTask;

Zwrócony typ void

Podstawowym zastosowaniem zwrócony typ void (Sub w języku Visual Basic) jest w procedurach obsługi zdarzeń, w których jest wymagane zwrócony typ void.Void zwrotu można również zastąpić metody zwracającej void lub dla metod, które wykonują czynności, które mogą zostać podzielone jako "ognia i zapomnieć." Jednakże, należy powrócić Task wszędzie tam, gdzie jest to możliwe, ponieważ metoda async zwracanie void nie oczekiwany.Wszystkim wywołującym taka metoda musi mieć możliwość dalszego do zakończenia bez oczekiwania na metody o nazwie asynchronicznej do końca, a obiekt wywołujący musi być niezależny od żadnych wartości lub wyjątków, które generuje metody asynchronicznej.

Obiekt wywołujący metodę komunikacji asynchronicznej zwracanie void nie może przechwytywać wyjątków, które są generowane przez metodę, a takie Nieobsłużone wyjątki są może spowodować awarię aplikacji.Jeśli wystąpi wyjątek w metodzie komunikacji asynchronicznej, która zwraca Task lub Task<TResult>, wyjątek jest przechowywane w zwracanych zadań i rethrown, gdy zadanie jest oczekiwany.W związku z tym, upewnij się, że każda metoda komunikacji asynchronicznej, która może spowodować wyjątek ma typ zwracany z Task lub Task<TResult> i oczekuje wywołania metody.

Aby uzyskać więcej informacji o sposobach przechwytywać wyjątków w metodach asynchronicznych, zobacz try-catch (C# odniesienia) lub Spróbuj...Catch...Instrukcja finally (Visual Basic).

Poniższy kod definiuje funkcję obsługi zdarzeń asynchronicznych.

' 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
// VOID EXAMPLE
private async void button1_Click(object sender, RoutedEventArgs e)
{
    textBox1.Clear();

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

    // Say goodbye.
    textBox1.Text += "\r\nAll done, exiting button-click event handler.";
}

Kompletny przykład

Następujący projekt Windows Presentation Foundation (WPF) zawiera przykłady kodu, z tego tematu.

Aby uruchomić projekt, należy wykonać następujące czynności:

  1. Uruchom program Visual Studio.

  2. Na pasku menu wybierz Plik, Nowy, projekt.

    Zostanie otwarte okno dialogowe Nowy projekt.

  3. W Installed, Szablony kategorii, wybierz polecenie języka Visual Basic lub Visual C#, a następnie wybierz polecenie systemu Windows.Wybierz polecenie Aplikacji WPF z listy typów projektów.

  4. Wprowadź AsyncReturnTypes jako nazwę projektu, a następnie wybierz polecenie OK przycisk.

    W Eksploratorze rozwiązań pojawi się nowy projekt.

  5. Wybierz Visual Studio Edytor kodu, MainWindow.xaml kartę.

    Jeśli karta nie jest widoczna, należy otworzyć menu skrótów dla MainWindow.xaml w Solution Explorer, a następnie wybierz polecenie Otwórz.

  6. W XAML okno MainWindow.xaml, kod ten zastąpić następujący kod.

    <Window x:Class="MainWindow"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://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>
    
    <Window x:Class="AsyncReturnTypes.MainWindow"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://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>
    

    Proste okno zawierające pola tekstowego i przycisku pojawia się w Projekt okno MainWindow.xaml.

  7. W Solution Explorer, otwórz menu skrótów dla MainWindow.xaml.vb lub MainWindow.xaml.cs, a następnie wybierz View Code.

  8. Zastąp kod w MainWindow.xaml.vb lub MainWindow.xaml.cs z następującego kodu.

    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 &= String.Format("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 &= String.Format(vbCrLf & "Value of result1 variable:   {0}" & vbCrLf, result1)
            textBox1.Text &= String.Format("Value of result2 variable:   {0}" & vbCrLf, result2)
            textBox1.Text &= String.Format("Value of resultTask.Result:  {0}" & vbCrLf, integerTask.Result)
    
            ' 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 &= String.Format(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 &= String.Format(vbCrLf & "Sorry for the delay. . . ." & vbCrLf)
    
            ' This method has no return statement, so its return type is Task. 
        End Function
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace AsyncReturnTypes
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            // VOID EXAMPLE
            private async void button1_Click(object sender, RoutedEventArgs e)
            {
                textBox1.Clear();
    
                // Start the process and await its completion. DriverAsync is a 
                // Task-returning async method.
                await DriverAsync();
    
                // Say goodbye.
                textBox1.Text += "\r\nAll done, exiting button-click event handler.";
            }
    
            async Task DriverAsync()
            {
                // Task<T> 
                // Call and await the Task<T>-returning async method in the same statement.
                int result1 = await TaskOfT_MethodAsync();
    
                // Call and await in separate statements.
                Task<int> integerTask = TaskOfT_MethodAsync();
    
                // You can do other work that does not rely on integerTask before awaiting.
                textBox1.Text += String.Format("Application can continue working while the Task<T> runs. . . . \r\n");
    
                int result2 = await integerTask;
    
                // Display the values of the result1 variable, the result2 variable, and
                // the integerTask.Result property.
                textBox1.Text += String.Format("\r\nValue of result1 variable:   {0}\r\n", result1);
                textBox1.Text += String.Format("Value of result2 variable:   {0}\r\n", result2);
                textBox1.Text += String.Format("Value of integerTask.Result: {0}\r\n", integerTask.Result);
    
                // Task
                // Call and await the Task-returning async method in the same statement.
                await Task_MethodAsync();
    
                // Call and await in separate statements.
                Task simpleTask = Task_MethodAsync();
    
                // You can do other work that does not rely on simpleTask before awaiting.
                textBox1.Text += String.Format("\r\nApplication can continue working while the Task runs. . . .\r\n");
    
                await simpleTask;
            }
    
            // TASK<T> EXAMPLE
            async Task<int> TaskOfT_MethodAsync()
            {
                // The body of the method is expected to contain an awaited asynchronous
                // call.
                // Task.FromResult is a placeholder for actual work that returns a string.
                var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());
    
                // The method then can process the result in some way.
                int leisureHours;
                if (today.First() == 'S')
                    leisureHours = 16;
                else
                    leisureHours = 5;
    
                // Because the return statement specifies an operand of type int, the
                // method must have a return type of Task<int>.
                return leisureHours;
            }
    
    
            // TASK EXAMPLE
            async Task Task_MethodAsync()
            {
                // 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);
                // Task.Delay delays the following line by two seconds.
                textBox1.Text += String.Format("\r\nSorry for the delay. . . .\r\n");
    
                // This method has no return statement, so its return type is Task.  
            }
        }
    }
    
  9. Wybierz klawisz F5, aby uruchomić program, a następnie wybierz Start przycisk.

    Powinien pojawić się następujące dane wyjściowe.

    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.
    

Zobacz też

Zadania

Instruktaż: Dostęp do sieci Web za pomocą transmisji asynchronicznej i poczekać (C# i Visual Basic)

Wskazówki: Korzystanie z debugera i metod asynchronicznych

Informacje

Asynchroniczne (C# odniesienia)

Asynchroniczne (Visual Basic)

Poczekać operatora (Visual Basic)

poczekać (C# odniesienia)

FromResult<TResult>

Koncepcje

Przepływ sterowania w programach Async (C# i Visual Basic)