非同期メソッドには、 Task<TResult>、 Task、void の 3 つの戻り値の型があります。 Visual Basic では、void の戻り値の型は Sub プロシージャとして記述されます。 非同期メソッドの詳細については、「Async および Await を使用した非同期プログラミング (Visual Basic)」を参照してください。
各戻り値の型は次のいずれかのセクションで調べられ、トピックの最後に 3 つの型をすべて使用する完全な例があります。
注
この例を実行するには、Visual Studio 2012 以降と .NET Framework 4.5 以降がコンピューターにインストールされている必要があります。
Task(T) 戻り値の型
Task<TResult>戻り値の型は、オペランドが型TResult
を持つ Return ステートメントを含む非同期メソッドに使用されます。
次の例では、 TaskOfT_MethodAsync
非同期メソッドに整数を返す return ステートメントが含まれています。 そのため、メソッド宣言では、 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
await 式内からTaskOfT_MethodAsync
が呼び出されると、await 式は、TaskOfT_MethodAsync
によって返されるタスクに格納されている整数値 (leisureHours
の値) を取得します。 await 式の詳細については、「 Await 演算子」を参照してください。
次のコードは、メソッド TaskOfT_MethodAsync
を呼び出して待機します。 結果は result1
変数に割り当てられます。
' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()
次のコードに示すように、 TaskOfT_MethodAsync
の呼び出しを Await
のアプリケーションから分離することで、この動作をより深く理解できます。 メソッドの宣言から予想されるように、直ちに待機しない TaskOfT_MethodAsync
メソッドの呼び出しは、Task(Of Integer)
を返します。 この例では、タスクは integerTask
変数に割り当てられます。
integerTask
は Task<TResult>であるため、Result型の TResult
プロパティが含まれています。 この場合、TResult は整数型を表します。
Await
が integerTask
に適用されると、await 式は Resultの integerTask
プロパティの内容に評価されます。 この値は、result2
変数に割り当てられます。
Warnung
Result プロパティはブロッキング プロパティです。 タスクが完了する前にアクセスしようとすると、タスクが完了して値が使用可能になるまで、現在アクティブなスレッドはブロックされます。 ほとんどの場合、プロパティに直接アクセスするのではなく、Await
を使用して値にアクセスする必要があります。
' 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
次のコードの表示ステートメントは、 result1
変数、 result2
変数、および Result
プロパティの値が同じであることを確認します。
Result
プロパティはブロック プロパティであり、タスクが待機される前にアクセスしないでください。
' 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
タスクの戻り値の種類
return ステートメントを含まない非同期メソッド、またはオペランドを返さない return ステートメントを含む非同期メソッドには、通常、戻り値の型が Task。 同期的に実行するように記述された場合、このようなメソッドは Sub プロシージャになります。 非同期メソッドに Task
戻り値の型を使用する場合、呼び出し元のメソッドは、呼び出された非同期メソッドが完了するまで呼び出し元の完了を中断する Await
演算子を使用できます。
次の例では、非同期メソッド Task_MethodAsync
には return ステートメントが含まれません。 そのため、メソッドの Task
の戻り値の型を指定すると、 Task_MethodAsync
を待機できます。
Task
型の定義には、戻り値を格納するためのResult
プロパティは含まれません。
' 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
は、同期 Sub
または void を返すメソッドの呼び出し元のステートメントと同様に、await 式ではなく await ステートメントを使用して呼び出され、待機されます。 この場合、 Await
演算子を適用しても値は生成されません。
次のコードは、メソッド Task_MethodAsync
を呼び出して待機します。
' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()
前の Task<TResult> 例と同様に、次のコードに示すように、 Task_MethodAsync
の呼び出しを Await
演算子のアプリケーションから分離できます。 ただし、Task
には Result
プロパティがなく、await 演算子が Task
に適用されるときに値が生成されない点に注意してください。
次のコードでは、呼び出し元の Task_MethodAsync
と、 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
Void 戻り値の型
Sub
プロシージャの主な用途は、戻り値の型がないイベント ハンドラー (他の言語では void 戻り値の型と呼ばれます) です。 void 戻り値は、void を返すメソッドをオーバーライドしたり、"fire and forget" として分類できるアクティビティを実行するメソッドに使用することもできます。ただし、void を返す非同期メソッドを待機できないため、可能な限り Task
を返す必要があります。 このようなメソッドの呼び出し元は、呼び出された非同期メソッドが終了するのを待たずに完了を続けることができ、呼び出し元は非同期メソッドが生成する値または例外から独立している必要があります。
void を返す非同期メソッドの呼び出し元は、メソッドからスローされた例外をキャッチできません。このようなハンドルされない例外により、アプリケーションが失敗する可能性があります。 TaskまたはTask<TResult>を返す非同期メソッドで例外が発生した場合、例外は返されたタスクに格納され、タスクが待機しているときに再スローされます。 したがって、例外を生成できる非同期メソッドの戻り値の型が Task または Task<TResult> であり、メソッドの呼び出しが待機されていることを確認します。
非同期メソッドで例外をキャッチする方法の詳細については、「 Try..」を参照してください。捕まえる。。。Finally ステートメント。
次のコードでは、非同期イベント ハンドラーを定義します。
' 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
コード例全体
次の Windows Presentation Foundation (WPF) プロジェクトには、このトピックのコード例が含まれています。
プロジェクトを実行するには、次の手順を実行します。
Visual Studio を起動します。
メニュー バーで、 [ファイル] 、 [新規作成] 、 [プロジェクト] の順にクリックします。
[ 新しいプロジェクト ] ダイアログ ボックスが開きます。
[インストール済み] の [テンプレート] カテゴリで、[Visual Basic] を選択し、[Windows] を選択します。 プロジェクトの種類の一覧から WPF アプリケーション を選択します。
プロジェクトの名前として「
AsyncReturnTypes
」と入力し、[ OK] ボタンを選択します。ソリューション エクスプローラーに新しいプロジェクトが表示されます。
Visual Studio コード エディターで、 [MainWindow.xaml] タブをクリックします。
タブが表示されない場合は、 ソリューション エクスプローラーで MainWindow.xaml のショートカット メニューを開き、[ 開く] を選択します。
MainWindow.xaml の XAML ウィンドウで、コードを次のコードに置き換えます。
<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>
テキスト ボックスとボタンを含む単純なウィンドウが MainWindow.xaml の デザイン ウィンドウに表示されます。
ソリューション エクスプローラーで MainWindow.xaml.vb のショートカット メニューを開き、 [コードの表示] を選択します。
MainWindow.xaml.vbのコードを次のコードに置き換えます。
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
F5 キーを押してプログラムを実行し、[ スタート ] ボタンを選択します。
次の出力が表示されます。
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.
こちらも参照ください
.NET