VB.NET スレッドの使い方

(Visual Studio 2015 版)

投稿日 2015/10/17

[Home] | VB.NET インデックス

概要

Windows.Forms アプリケーションでは BackgroundWorker コントロールを使ったほうが、バックグランド動作を記述するのは簡単ですが、スレッドを使うこともできます。この場合、スレッドから直接、フォーム上のコントロールを操作できないことに注意します。そのような場合は、フォームのメソッド Invoke を経由して操作を行う必要があります。

スレッドとフォームの間で通信を行うには、直接メソッドを呼び出すことができないので、イベントやコールバックを使用する必要があります。


サンプルプログラム

次のサンプルプログラムは、Start ボタンをクリックすると1秒ごとにカウントダウンを開始して、5秒経過するとカントダウンを終了します。

プログラムは次の3つのファイルに分かれています。


Form1.vb

Public Class Form1
    Private workerThread As Worker  ' ワーカースレッド
    Public Completed As Action  ' スレッドが終わった時のイベント
    
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    Public Sub New()
    
        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()
        
        ' ワーカースレッドを作成する。
        workerThread = New Worker()
        workerThread.ParentForm = Me  ' 親フォームとして自分を設定する。
        ' スレッドからメッセージを受けるメソッドを設定する。
        workerThread.Notify = AddressOf Receiver
        ' スレッドが終了したときのイベントハンドラを設定する。
        AddHandler workerThread.Completed, AddressOf DoCompleting
    End Sub
    
    ''' <summary>
    ''' Start ボタンがクリックされたとき
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        workerThread.Start()
        Button1.Enabled = False
        Label1.Text = "0 秒"
    End Sub
    
    ''' <summary>
    ''' スレッドからメッセージを受けるメソッド
    ''' </summary>
    ''' <param name="message"></param>
    Private Sub Receiver(ByVal message As String)
        Label1.Text = message
    End Sub
    
    ''' <summary>
    ''' スレッドが終わった時のイベントハンドラ
    ''' </summary>
    Private Sub DoCompleting()
        MessageBox.Show("バックグランド動作が完了しました。", "通知")
        Label1.Text = ""
        Button1.Enabled = True
    End Sub
End Class

AbstractWorker.vb

''' <summary>
''' ワーカースレッド
''' </summary>
Public MustInherit Class AbstractWorker
    ' スレッド
    Private workerThread As Threading.Thread
    
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    Public Sub New()
        ' workerThread = New Threading.Thread(AddressOf Run)
    End Sub
    
    ''' <summary>
    ''' スレッドを開始する。
    ''' </summary>
    Public Sub Start()
        workerThread = New Threading.Thread(AddressOf Run)
        workerThread.Start()
    End Sub
    
    ''' <summary>
    ''' スレッドを終了する。
    ''' </summary>
    Public Sub Terminate()
        workerThread.Abort()
    End Sub
    
    ''' <summary>
    ''' バックグランド動作をする抽象メソッド
    ''' </summary>
    Protected MustOverride Sub Run()
End Class

Worker.vb

''' <summary>
'''  バックグランドワーカー
''' </summary>
Public Class Worker : Inherits AbstractWorker
    ' 終了通知イベント
    Public Event Completed As Action
    ' 親のフォーム
    Public Property ParentForm As Form
    ' 状態通知用のデリゲート
    Public Delegate Sub NotifyStatus(ByVal status As String)
    Public Notify As NotifyStatus
    
    ''' <summary>
    ''' バックグランド動作メソッド
    ''' </summary>
    Protected Overrides Sub Run()
        Dim i = 0
        While i < 5
            ' 1秒間スリープする。
            Threading.Thread.Sleep(1000)
            i += 1
            ' 途中経過を通知
            ParentForm.Invoke(Notify, i.ToString() & " 秒")
        End While
        ' 終了通知
        RaiseEvent Completed()
    End Sub
End Class

 

 


 

 開設 2014年12月   著作権 2014-2015 bonk.red  連絡先: こちらからメッセージを送ってください。

 このページの先頭へ..