Async および Await を使用した非同期プログラミング (C# および Visual Basic)
詳細はリンク先の通りのため詳細の説明は省き、カンペ化する。
非同期メソッド実処理
専用
Public Async Function GetMessageAsync(timer As Integer) As Task(Of String) Dim rtn As String = String.Empty Await Task.Run(Sub() '重い処理 Threading.Thread.Sleep(timer) rtn = "Hello, world" End Sub) Return rtn End Function
汎用
Task.Factory.StartNew を使って、既存処理をTaskに変換する。
Private Function GetMessage(timer As Integer) As String Threading.Thread.Sleep(timer) Return "Hello, world" End Function
'How to use Dim tk = Task.Factory.StartNew(Function() Me.GetMessage(5000))
非同期メソッド呼び出し元
非同期
Private Async Sub RunAsAsync() Dim tk = Me.GetMessageAsync(5000) Dim rtn As String = Await tk Debug.Print(rtn) End Sub
非同期(複数、すべて完了すると後続処理が再開)
Private Async Sub RunAsAsyncWhenAll Dim tk1 = Me.GetMessageAsync(1000) Dim tk2 = Me.GetMessageAsync(3000) Dim tk3 = Me.GetMessageAsync(5000) Await Task.WhenAll({tk1, tk2, tk3}) Debug.Print("End : " & tk1.Result & ", " & tk2.Result & ", " & tk3.Result) End Sub
非同期(複数、一部が終了すると後続処理が再開)
Private Async Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click Dim tk1 = Me.GetMessageAsync(1000) Dim tk2 = Me.GetMessageAsync(3000) Dim tk3 = Me.GetMessageAsync(5000) Await Task.WhenAny({tk1, tk2, tk3}) If tk1.IsCompleted Then logger.Info("End(tk1) : " & tk1.Result) If tk2.IsCompleted Then logger.Info("End(tk2) : " & tk2.Result) If tk3.IsCompleted Then logger.Info("End(tk3) : " & tk3.Result) End Sub
この場合、
End(tk1) : Hellow, world
のみ出力がされます、「End(tk2)、End(tk3)」は出力されません。
また、tk1、tk2、tk3のResultにアクセスる前まえに、必ずIsCompleteで処理が完了しているか評価する必要があります。 評価前にアクセスするとハングするので要注意。