忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

引数があるスレッドの実行について(パラメータ付きスレッド)

スレッドの関数に引数を渡して別々の処理をさせたい場合があると思いますが、 スレッドを生成する時にアドレス指定のところに ParameterizedThreadStart デリゲートを使うことで可能です。
以下に実行プログラムの例を示します。

引数があるスレッドの実行プログラム

Imports System
Imports System.Threading

Module ThreadParam

    'メイン関数(エントリーポイント)
    Sub Main()
        '[ParameterizedThreadStart]デリゲートを使ったスレッド生成
        Dim pThread As Thread = New Thread(New ParameterizedThreadStart(AddressOf ThreadParam))
        '(ParameterizedThreadStart)の指定が無くてもOKですが
        'Dim pThread As Thread = New Thread(AddressOf ThreadParam)

        'スレッド開始
        pThread.Start("スレッド...")
        Console.WriteLine("スレッド開始")
    End Sub

    '引数を持つスレッド関数(引数は1個のオブジェクトのみ)
    Sub ThreadParam(ByVal obj As Object)
        For i As Integer = 1 To 5
            Threading.Thread.Sleep(1000)
            Console.WriteLine(obj.ToString())
        Next
    End Sub

End Module

取敢えず、実行結果がコンソールに以下の様に表示されます。

スレッド開始
スレッド...
スレッド...
スレッド...
スレッド...
スレッド...

ParameterizedThreadStart の利用は引数が1個なので複数のデータを渡す場合には 配列等(リストオブジェクト等)にして、スレッド関数側で配列の内容について処理を規定する必要があります。
以下に引数をオブジェクトの配列として渡す場合の例を示します。

引数があるスレッドの実行プログラム2

Imports System
Imports System.Threading

Module ThreadParam

    'メイン関数(エントリーポイント)
    Sub Main()
        '[ParameterizedThreadStart]デリゲートを使ったスレッド生成
        Dim pThread As Thread = New Thread(New ParameterizedThreadStart(AddressOf ThreadParam))

        'オブジェクト配列データ設定
        Dim arrObj(2) As Object
        arrObj(0) = "1111"
        arrObj(1) = 12345
        arrObj(2) = True

        'スレッド開始
        pThread.Start(arrObj)
        Console.WriteLine("スレッド開始")
    End Sub

    '引数を持つスレッド関数(引数は1個のオブジェクトのみ)
    Sub ThreadParam(ByVal obj As Object)
        '引数をオブジェクト配列として扱う
        Dim pArr As Object() = CType(obj, Object())
        For i As Integer = 0 To pArr.Length - 1
            Threading.Thread.Sleep(1000)
            Console.WriteLine(pArr(i).ToString())
        Next
    End Sub

End Module

引数にして渡さなくても、スレッド実行をラップする様なクラスを導入して コンストラクタの引数でデータ型を規定することもできます。
以下に、スレッドを実行するためのクラスを導入した例を示します。

スレッドの引数としてクラスでラップした実行プログラム

Imports System
Imports System.Threading

Module ThreadParam

    'メイン関数(エントリーポイント)
    Sub Main()
        'スレッド用クラスの生成
        Dim pclsThread As New clsThread(12345, "AAA", False)

        'スレッド開始
        pclsThread.Start()
        Console.WriteLine("スレッド開始")
    End Sub

    'スレッド用クラス
    Class clsThread
        'クラス生成時に退避されるデータ群
        Private mintData As Integer
        Private mstrData As String
        Private mblnData As Boolean

        'コンストラクタ
        Sub New(ByVal aintData As Integer,
                ByVal astrData As String,
                ByVal ablnData As Boolean)
            Me.mintData = aintData
            Me.mstrData = astrData
            Me.mblnData = ablnData
        End Sub

        '内部スレッドの開始メソッド
        Sub Start()
            Dim pThread As Thread = New Thread(AddressOf ThreadProc)
            'スレッド開始
            pThread.Start()
        End Sub

        'スレッド関数(この関数はプライベート)
        Private Sub ThreadProc()
            Threading.Thread.Sleep(1000)
            Console.WriteLine("Integer Data = " & Me.mintData)
            Threading.Thread.Sleep(1000)
            Console.WriteLine("String Data = " & Me.mstrData)
            Threading.Thread.Sleep(1000)
            Console.WriteLine("Boolean Data = " & Me.mblnData)
        End Sub

    End Class

End Module

実行結果は以下の様に表示されます。

スレッド開始
Integer Data = 12345
String Data = AAA
Boolean Data = False

スレッドを含む処理をクラスの中に入れ込んで、 その中で開始や停止などを行った方がスレッド処理を呼出す側との処理の分離がうまくいくと思います。

PR

コメント

コメントを書く