Async/awaite&backgroundWorkerを使ったスレッド処理

Imports System.ComponentModel
Imports System.Threading
Public Class Form1

Dim cts As CancellationTokenSource

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim bgWorker As BackgroundWorker = DirectCast(sender, BackgroundWorker)

Dim i As Integer

'ループ終了かキャンセルされた時まではループ続ける
For i = 1 To 10
If bgWorker.CancellationPending Then
'キャンセルされたとき
e.Cancel = True
Return
End If

System.Threading.Thread.Sleep(500)

bgWorker.ReportProgress(i)
Next

e.Result = 10
Form2.Label1.Text = "10deg"

End Sub

'スレッド中の処理
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) _
Handles BackgroundWorker1.ProgressChanged

'Label1のテキストを変更する
Form2.Label1.Text = e.ProgressPercentage.ToString() & "deg"
Form2.Label2.Text = "目標は10deg"

End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object,
ByVal e As RunWorkerCompletedEventArgs) _
Handles BackgroundWorker1.RunWorkerCompleted

If Not e.Error Is Nothing Then
'エラーが発生したとき
Label1.Text = "エラー:" & e.Error.Message
ElseIf e.Cancelled Then
'キャンセルされたとき
Else
'正常に終了したとき
'結果を取得する
Dim result As Integer = CInt(e.Result)
Label1.Text = result.ToString() & "deg"
End If

Thread.Sleep(1000)

Form2.Close()

Button1.Enabled = True
Button2.Enabled = False

End Sub

'スレッド開始
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

cts = New CancellationTokenSource()

'処理が行われているときは、何もしない
If BackgroundWorker1.IsBusy Then
Return
End If

Try

'BackgroundWorkerのProgressChangedイベントが発生するようにする
BackgroundWorker1.WorkerReportsProgress = True

'キャンセルできるようにする
BackgroundWorker1.WorkerSupportsCancellation = True

Form2.Show()

'BackgroundWorker処理開始
BackgroundWorker1.RunWorkerAsync()

Dim t = posi_move(cts.Token)
Await t

Catch ex As Exception
MessageBox.Show("キャンセルされました")
End Try

Button3.Enabled = True
Button4.Enabled = False

End Sub

'スレッド中の処理
Async Function posi_move(token As CancellationToken) As Task(Of Task)

Dim a As Integer
Dim c As Integer = 0

Button3.Enabled = False
Button4.Enabled = True

Dim result As Task = Task.Run(
Sub()
While True

For a = 1 To 10

If (token.IsCancellationRequested) Then 'キャンセル時の処理
c = 1
Exit While
End If

Thread.Sleep(500)
Next

Exit While

End While
End Sub
)
Await result

If c = 1 Then
MessageBox.Show("中断しました")
Else
MessageBox.Show("タスク終了")
End If

Return result

End Function

'スレッド停止
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

Label1.Text = Form2.Label1.Text

Form2.Close()

'キャンセルする
BackgroundWorker1.CancelAsync()

cts.Cancel()

End Sub
End Class