サイトアイコン 成功者への道

【VB.NET】BackgroundWorkerでスレッド処理を使いこなす

マルチスレッド?なんだそりゃという方のためにスレッドについて簡単に説明します。

スレッドとは直訳すると、撚り糸、筋、脈絡という意味ですが、プログラム世界では最小の処理単位のことを言います。

マルチスレッドとは同時に複数の処理を行うことを指します。

 

具体的に説明をすると、「歩く」というスレッドと「スマホをいじる」というスレッドがあるとします。

その場合、「歩きスマホ」がマルチスレッドということになります。

10分間歩き、10分間スマホをいじる場合に、別々に行うと計20分かかります。

それをメインスレッドが「歩く」バックグラウンドのスレッドが「スマホをいじる」を同時に行うことで10分で完了できます。

例に挙げましたが、歩きスマホは危険なのでやめましょう!!

VB.NETで仕様できるスレッドにはいくつか種類がありますが、ここではBackgroundWorkerの使い方を説明します。

事前準備

BackgroundWokerを使用するためには、ツールボックスからBackgroundWokerをFormにドラッグ&ドロップします。

下記のようになればBackgroundWokerを使う準備はOKです。

※名称が長いため、BackgroundWoker1をbgwとします。

 

スレッド処理したい処理を書く

Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    For I As Integer = 1 To 100
       'ここに時間のかかる処理を書く
    Next
End Sub

 

処理の実行

RunWorkerAsyncメソッドを実行します。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

     bgw.RunWorkerAsync()

End Sub

 

処理状況を通知

メインスレッドとバックグラウンドのスレッドは別スレッドの処理のため互いがどんな状況にあるかがわかりません。

そこで、バックグラウンドスレッドがメインスレッドに状況を通知するために使用するのがProgressChangedイベントです。

代表的なもので、プログレスバーがあります。

100回の処理があり、1つ終わるごとに1%の処理が完了したものとするとしましょう。

その場合に、メインスレッドに完了の通知を投げることができます。

ここで注意すべきなのが、あくまでも通知ができるものなのでProgressChanged内でメインスレッドとなる親のコントロール(テキストボックスやラベルなど)に対してアクセスすることはできません。

また、事前にWorkerReportsProgress=Trueにする必要があります。

通知する側

Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    For i As Integer = 1 To 100
        '〜時間のかかる処理〜
        'ProgressChangedイベントで処理状況を通知
        bgw.ReportProgress(i
    Next
End Sub

 

受ける側

Private Sub bgw_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
    'プログレスバーを更新
    ProgressBar1.Value = e.ProgressPercentage
End Sub

 

処理完了を通知

RunWorkerCompletedイベントを使用します。

' バックグラウンド処理完了時の処理
Private Sub bgw_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
    MessageBox.Show("処理が完了しました。")
End Sub

 

キャンセルをするには

CancelAsyncを使用します。

また、事前にWorkerSupportsCancellation=Trueにする必要があります。

Private Sub btnCancel_Click(sender As System.Object, e As System.EventArgs) Handles btnCancel.Click
    '処理が実行中か?
    If bgw.IsBusy Then
        'キャンセル
        bgw.CancelAsync()
    End If
End Sub

 

 

モバイルバージョンを終了