因みに、Task.Runにキャンセルトークンを渡さないで、ラムダ式で引数としてtokenを渡す場合は、次のようにすると上手くいきました。
Private Async Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
tokenSource = New CancellationTokenSource
Debug.Print($"StartTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
Try
Await Task.Run(Function()
Return Test2(tokenSource.Token)
End Function)
Finally
tokenSource.Dispose()
End Try
Debug.Print($"FinishTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
End Sub
Async Function Test2(ByVal token As CancellationToken) As Task
Dim i As Integer = 0
Debug.Print($"子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
Dim 孫Task As Task = Task.Run(
Sub()
Dim j As Integer = 0
Debug.Print($"孫子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
While j < 7
If token.IsCancellationRequested Then
Debug.Print("孫Taskは、停止しました。")
Exit While
End If
Thread.Sleep(500) '0.5秒待つ
Debug.Print($"孫TaskCount:{j}")
j += 1
End While
End Sub)
While i < 5
If token.IsCancellationRequested Then
Debug.Print("子Taskは、停止しました。")
Exit While
End If
Thread.Sleep(500) '0.5秒待つ
Debug.Print($"子TaskCount:{i}")
i += 1
End While
Await 孫Task
End Function
「Taskの入れ子の待ち方」の続きです。
子Taskをラムダ式からメソッドへのデリゲートに変え、Task.Runにキャンセルトークンを渡すように変更したコードが次の通りです。
Dim tokenSource As New CancellationTokenSource
Private Async Sub Button6_Click(sender As Object, e As EventArgs)
tokenSource = New CancellationTokenSource
Debug.Print($"StartTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
Try
Await Task.Run(AddressOf Test, tokenSource.Token)
Finally
tokenSource.Dispose()
End Try
Debug.Print($"FinishTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
End Sub
Async Function Test() As Task
Dim i As Integer = 0
Debug.Print($"子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
Dim 孫Task As Task = Task.Run(
Sub()
Dim j As Integer = 0
Debug.Print($"孫子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
While j < 7
If token.IsCancellationRequested Then
Debug.Print("孫Taskは、停止しました。")
Exit While
End If
Thread.Sleep(500) '0.5秒待つ
Debug.Print($"孫TaskCount:{j}")
j += 1
End While
End Sub)
While i < 5
If token.IsCancellationRequested Then
Debug.Print("子Taskは、停止しました。")
Exit While
End If
Thread.Sleep(500) '0.5秒待つ
Debug.Print($"子TaskCount:{i}")
i += 1
End While
Await 孫Task
End Function
すると、当然、Testメソッドにtokenの引数が無いので、Testメソッド側でtokenが認識できません。当然のように思えます。
ネットでググっても、Testメソッドの引数にキャンセルトークンを渡しているものばかりが見つかります。
ってことは、Task.Runで、キャンセルトークンを渡す必要性がそもそも無いということになるように思いますが、間違っていますでしょうか?何のためにキャンセルトークンをTask.Runで渡すのでしょうか?
「Taskの入れ子の待ち方」では、ラムダ式で渡していたので、Task.Runでtokenを渡さなくてもメインスレッドのtokenの状態を確認することができました。
Task.Runで、キャンセルトークンを渡しているので、孫タスク側で何か?うまい方法でtokenを認識する方法は?無いものでしょうか?
質問の意図が通じますでしょうか?
宜しくお願い致します。