Sdílet prostřednictvím


Typy vrácení asynchronní (C# a Visual Basic)

Asynchronní metody mají tři možné návratové typy: Task<TResult>, Taska od počátku neplatné.V jazyce Visual Basic je typ vrácené hodnoty void zapsán jako Sub postup.Další informace o asynchronní metody naleznete v tématu Asynchronní asynchronní pro programování a očekávat (C# a Visual Basic).

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

[!POZNÁMKA]

Chcete-li spustit příklad, musíte mít Visual Studio 2012, Visual Studio Express 2012 pro program Windows Desktop, nebo 4.5 rozhraní .NET Framework, ve vašem počítači nainstalována.

Toto téma obsahuje následující oddíly.

  • Návratový typ Task(T)
  • Návratový typ úkolu
  • Typ vrácené hodnoty void
  • Kompletní příklad
  • Příbuzná témata

Návratový typ Task(T)

Task<TResult> Vrátí typ se používá pro asynchronní metodu, která obsahuje vrátit (Visual Basic) nebo vrátit (C#) prohlášení, ve kterém operand je typu TResult.

V následujícím příkladu TaskOfT_MethodAsync asynchronní metody obsahuje příkaz return, která vrátí hodnotu typu integer.Proto deklarace metody musíte zadat návratový typ Task(Of Integer) v jazyce Visual Basic nebo Task<int> v jazyce 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;
}

Při TaskOfT_MethodAsync je volána z ve výrazu await načte výraz await celočíselná hodnota (hodnota leisureHours) uloženy v úkolu, který je vrácen TaskOfT_MethodAsync.Další informace o vyčkání výrazů naleznete v tématu Vyčkání operátor (Visual Basic) nebo vyčkání (C#-Reference).

Následující kód volá a čeká metoda TaskOfT_MethodAsync.Výsledkem je přiřazen result1 proměnné.

' 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();

Můžete lépe pochopit, jak to se stane oddělením volání TaskOfT_MethodAsync z uplatňování Await nebo await, jak ukazuje následující kód.Volání metody TaskOfT_MethodAsync , není okamžitě awaited vrátí Task(Of Integer) nebo Task<int>, jak byste očekávali od deklaraci metody.Úkol přidělen integerTask proměnné v příkladu.Protože integerTask je Task<TResult>, obsahuje Result vlastnost typu TResult.V tomto případě TResult představuje typ integer.Při Await nebo await u integerTask, await výraz vyhodnocen jako obsah Result vlastnost integerTask.Hodnota je přiřazena k result2 proměnné.

Poznámka k upozorněníUpozornění

Result Je blokování vlastnost.Pokud došlo k pokusu o přístup k před dokončením svých úkolů, podproces, který je aktuálně aktivní blokována, dokud dokončení úkolu a hodnotu je k dispozici.Ve většině případů byste měli přistupovat k hodnotě pomocí Await nebo await včetně přístupu k vlastnosti přímo.

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

Příkazy zobrazit následující kód ověřte, že hodnoty result1 proměnné, result2 proměnné a Result vlastnosti jsou stejné.Nezapomeňte, že Result vlastnost je blokování vlastnosti a neměli přístup před očekávané blahopřání svých úkolů.

' 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);

Návratový typ úkolu

Asynchronní metody, které neobsahují příkaz return nebo obsahující příkaz return, který nevrací operand obvykle mít návratový typ Task.Tyto metody by bylo zrušení vrácení metody (Sub procedury v jazyce Visual Basic) napsané spouštěny synchronně.Použijete-li Task návratový typ pro metodu asynchronní volání metody můžete použít operátor await pozastavit dokončení volajícího, dokud nebude dokončen jen asynchronní metody.

V následujícím příkladu metoda asynchronní Task_MethodAsync neobsahuje příkaz return.Proto určit návratový typ Task pro metodu, která umožňuje Task_MethodAsync Chcete-li být očekávané blahopřání.Definice Task neobsahuje typ Result vlastnost pro uložení návratovou hodnotu.

' 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_MethodAsyncje volána a očekávané blahopřání pomocí příkazu await namísto await výraz podobný synchronního volání příkazu Sub nebo metodu vracející void.Použití operátoru await v tomto případě nedává hodnotu.

Následující kód volá a čeká metoda 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();

Stejně jako v předchozích Task<TResult> příklad, lze oddělit volání Task_MethodAsync z uplatňování await operátor jako následující kód ukazuje.Nezapomeňte však, že Task nemá Result vlastnost a že žádná hodnota se vyrábí, když je použit operátor await Task.

Následující kód odděluje volací Task_MethodAsync z čekají na úkol, Task_MethodAsync 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 &= 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;

Typ vrácené hodnoty void

Primární použití typ vrácené hodnoty void (Sub procedury v jazyce Visual Basic) je v obslužné rutině události, kde je vyžadován typ vrácené hodnoty void.Neplatný návrat lze také přepsat metody vracející void nebo metody, které vykonávají činnosti, které lze rozdělit jako "požární a zapomenout." Nicméně, měli byste vrátit Task je to možné, protože asynchronní metody vracející void nelze imunofluorescenčním.Každému volajícímu taková metoda musí být schopna pokračovat až do ukončení bez čekání s názvem asynchronní metody na dokončení a volající musí být nezávislé na všechny hodnoty nebo které generuje asynchronní metody.

Volání asynchronní metody vracející void nelze zachytit výjimky, které jsou vyvolány z metody a tyto neošetřené výjimky mohou způsobit selhání aplikace.Pokud dojde k výjimce v asynchronní metodu, která vrací Task nebo Task<TResult>, výjimka je uložen ve vrácených úkolů a znovu vyvolány při imunofluorescenčním úkolu.Proto se ujistěte, že asynchronní metody, která může způsobit výjimku má návratový typ Task nebo Task<TResult> a že jsou imunofluorescenčním volání metody.

Další informace o tom, jak zachytit výjimky v asynchronní metody viz try-catch (C#-Reference) nebo Zkuste...Úlovek...Nakonec prohlášení (Visual Basic).

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

' 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.";
}

Kompletní příklad

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

Chcete-li spustit projekt, proveďte následující kroky:

  1. Spusťte aplikaci Visual Studio.

  2. V panelu nabídek zvolte Soubor, Nový, Projekt.

    Otevře se dialogové okno Nový projekt.

  3. V nainstalovat, šablony kategorie, zvolte jazyka Visual Basic nebo **Visual C#**a pak zvolte Windows.Zvolte Aplikace WPF ze seznamu typy projektů.

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

    V podokně Řešení - průzkumník se zobrazí nový projekt.

  5. V editoru Visual Studio kód, zvolte MainWindow.xaml kartu.

    Je-li na kartě není zobrazen, otevřete místní nabídku pro MainWindow.xaml v Průzkumníkua pak zvolte otevřete.

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

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

    Jednoduché okno, které obsahuje textové pole a tlačítko se zobrazí v Návrh okno MainWindow.xaml.

  7. V Průzkumníku, otevřete místní nabídku pro MainWindow.xaml.vb nebo MainWindow.xaml.cs a pak zvolte Zobrazit kód.

  8. Nahraďte kód ve MainWindow.xaml.vb nebo MainWindow.xaml.cs s 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 &= 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. Zvolte klávesu F5, chcete-li spustit program a pak zvolte Start tlačítko.

    By se měl 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é

Úkoly

Názorný postup: Přístup K webu pomocí asynchronní a vyčkání (C# a Visual Basic)

Postupy: Použití ladicího programu u asynchronních metod

Referenční dokumentace

asynchronní (C#-Reference)

Asynchronní (Visual Basic)

Vyčkání operátor (Visual Basic)

vyčkání (C#-Reference)

FromResult<TResult>

Koncepty

Řízení toku v programech asynchronní (C# a Visual Basic)