タスクを実行した際、途中でキャンセルしたいことがあります。その際の方法を記載します。
Taskクラス によるタスクキャンセルは、CancellationTokenSourceクラスを使用します。
タスクキャンセル要求は、CancellationTokenSource.Cancel()メソッドを実行します。
これによりキャンセルフラグが立ち、このフラグを参照することによりキャンセル処理を実行します。
ThrowIfCancellationRequested()によるキャンセル方法
オペレーション側プログラム
Dim cts As CancellationTokenSource Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click cts = New CancellationTokenSource() Try Dim t = ActionAsync(cts.Token) 'タスクの実行 Await t '非同期的に完了待ち Catch ex As OperationCanceledException MessageBox.Show("キャンセルされました") End Try End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click cts.Cancel() 'タスクのキャンセル要求 End Sub
タスク側プログラム(ThrowIfCancellationRequestedメソッド抜け出し)
Async Function ActionAsync(token As CancellationToken) As Task(Of Boolean) Dim result As Boolean = Await Task.Run( Function() As Boolean For i As Integer = 0 To 100 token.ThrowIfCancellationRequested() 'キャンセル時の処理 Thread.Sleep(1000) Next Return True End Function ) MessageBox.Show("タスク終了") Return result End Function
CancellationToken構造体のThrowIfCancellationRequested()メソッドで、キャンセルフラグをチェックします。
また、実際のキャンセルフラグは、CancellationToken.IsCancellationRequestedプロパティに設定されていて
このフラグが立ったらタスク側は、OperationCanceledException例外をスローするように作成します。
キャンセルフラグの例外スローのコードは、以下のコードのようになります。
If (token.IsCancellationRequested) Then Throw New OperationCanceledException(token) End If
上記を一文で書けるようにメソッドが用意されています。
token.ThrowIfCancellationRequested()
例外のスローではない IsCancellationRequestedでのキャンセル抜け出し
ThrowIfCancellationRequested()での抜け出しは、 例外スローするので、上に記載したコードではキャンセルの際、MessageBox.Show(“タスク終了”)実行されません。
そこで、IsCancellationRequestedを参照して抜け出すようにします。
タスク側プログラム(IsCancellationRequestedプロパティ抜け出し)
Async Function ActionAsync(token As CancellationToken) As Task(Of Task) Dim result As Task = Task.Run( Sub() While True If (token.IsCancellationRequested) Then 'キャンセル時の処理 Exit While End If Thread.Sleep(1000) End While End Sub ) Await result MessageBox.Show("タスク終了") Return result End Function