none
BackgroundWorker.DoWorkメソッドに固有の情報を与えたい RRS feed

  • 質問

  • BackgroundWorkerを使い、CPUの数-1 という個数のスレッドを同時に動作させたいと思っています。
    ここで、スレッド処理の中で「何番目のスレッドか」という情報を扱いたいのですが、実現方法が分かりません。

    ソースリストでは、3つのスレッドを起動させますが、それぞれに「0」、「1」、「2」という識別情報を与えているのですが、(当然ながら)いずれも「2」という情報が送られてしまいます。

    これ以上の解決方法は私には考え付かないので、御教授を御願い致します。

    ↓ Debug.Printの出力 0,1,2が識別されていない。
    2
    2
    (2)が開始されました。
    (2)が終了しました。
    2
    (2)が開始されました。
    (2)が開始されました。
    (2)が終了しました。
    BW_RunWorkerCompleted
    (2)が終了しました。
    BW_RunWorkerCompleted
    BW_RunWorkerCompleted

    ’ソース

    Imports System.ComponentModel

    Class MainWindow
        'スレッドの識別番号を格納する配列
        Dim Arr1 As New List(Of Integer)
        'スレッドを格納する配列
        Public Property BWArr As New List(Of BackgroundWorker)
        'BW_Doworkにスレッドの識別番号を与えたいが、うまく動かない
        Public Property BWArr_Index As Integer


        Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded

            'スレッドの識別番号 CPUの数-1だけ要素を追加するものとする
            Arr1.Add(0)
            Arr1.Add(1)
            Arr1.Add(2)

            Dim _bw As BackgroundWorker
            Dim i As Integer
            For i = 0 To Arr1.Count - 1

                _bw = New BackgroundWorker
                BWArr.Add(_bw)

                _bw.WorkerReportsProgress = True
                _bw.WorkerSupportsCancellation = True

                'BW_Doworkメソッドに対してスレッドの識別番号を与えたい
                BWArr_Index = i

                AddHandler _bw.DoWork, AddressOf BW_Dowork
                AddHandler _bw.ProgressChanged, AddressOf BW_ProgressChanged
                AddHandler _bw.RunWorkerCompleted, AddressOf BW_RunWorkerCompleted
                ' BW_Doworkを実行する
                _bw.RunWorkerAsync()

            Next

        End Sub

        'スレッド開始
        Private Sub BW_Dowork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
            'BW_Doworkメソッドに対してスレッドの識別番号を与えたい
            Dim i As Integer = BWArr_Index
            Debug.Print(i)

            Debug.Print(String.Format("({0})が開始されました。", BWArr_Index))
            Debug.Print(String.Format("({0})が終了しました。", BWArr_Index))
            GC.Collect()

        End Sub

        Private Sub BW_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)

        End Sub

        '処理終了
        Private Sub BW_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
            Debug.Print("BW_RunWorkerCompleted")
        End Sub

    End Class
    2018年1月18日 2:04

回答

  • スレッドに何番目のスレッドかを表す整数値を渡したいということですね。

    RunWorkerAsync メソッドに数値をそのまま渡すのはどうでしょうか?BW_Dowork メソッドでは e.Argument で取り出すことができます。下記に全体のコードを示します。

    Imports System.ComponentModel
    
    Class MainWindow
        'スレッドの識別番号を格納する配列
        Dim Arr1 As New List(Of Integer)
        'スレッドを格納する配列
        Public Property BWArr As New List(Of BackgroundWorker)
    
        Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    
            'スレッドの識別番号 CPUの数-1だけ要素を追加するものとする
            Arr1.Add(0)
            Arr1.Add(1)
            Arr1.Add(2)
    
            Dim _bw As BackgroundWorker
            Dim i As Integer
            For i = 0 To Arr1.Count - 1
                _bw = New BackgroundWorker
                BWArr.Add(_bw)
    
                _bw.WorkerReportsProgress = True
                _bw.WorkerSupportsCancellation = True
    
                AddHandler _bw.DoWork, AddressOf BW_Dowork
                AddHandler _bw.ProgressChanged, AddressOf BW_ProgressChanged
                AddHandler _bw.RunWorkerCompleted, AddressOf BW_RunWorkerCompleted
    
                '何番目かを示す整数値を渡してBW_Doworkを実行する
                _bw.RunWorkerAsync(i)
    
            Next
        End Sub
    
        'スレッド開始
        Private Sub BW_Dowork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
            'BW_Doworkメソッドに対してスレッドの識別番号を与えたい
            Dim i As Integer = e.Argument
    
            Debug.Print(i)
    
            Debug.Print(String.Format("({0})が開始されました。", i))
            Debug.Print(String.Format("({0})が終了しました。", i))
            GC.Collect()
        End Sub
    
        Private Sub BW_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
        End Sub
    
        '処理終了
        Private Sub BW_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
            Debug.Print("BW_RunWorkerCompleted")
        End Sub
    End Class
    参考サイト: https://stackoverflow.com/questions/4807152/sending-arguments-to-background-worker
    • 回答としてマーク huahi11112 2018年1月18日 2:55
    2018年1月18日 2:21

すべての返信

  • スレッドに何番目のスレッドかを表す整数値を渡したいということですね。

    RunWorkerAsync メソッドに数値をそのまま渡すのはどうでしょうか?BW_Dowork メソッドでは e.Argument で取り出すことができます。下記に全体のコードを示します。

    Imports System.ComponentModel
    
    Class MainWindow
        'スレッドの識別番号を格納する配列
        Dim Arr1 As New List(Of Integer)
        'スレッドを格納する配列
        Public Property BWArr As New List(Of BackgroundWorker)
    
        Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    
            'スレッドの識別番号 CPUの数-1だけ要素を追加するものとする
            Arr1.Add(0)
            Arr1.Add(1)
            Arr1.Add(2)
    
            Dim _bw As BackgroundWorker
            Dim i As Integer
            For i = 0 To Arr1.Count - 1
                _bw = New BackgroundWorker
                BWArr.Add(_bw)
    
                _bw.WorkerReportsProgress = True
                _bw.WorkerSupportsCancellation = True
    
                AddHandler _bw.DoWork, AddressOf BW_Dowork
                AddHandler _bw.ProgressChanged, AddressOf BW_ProgressChanged
                AddHandler _bw.RunWorkerCompleted, AddressOf BW_RunWorkerCompleted
    
                '何番目かを示す整数値を渡してBW_Doworkを実行する
                _bw.RunWorkerAsync(i)
    
            Next
        End Sub
    
        'スレッド開始
        Private Sub BW_Dowork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
            'BW_Doworkメソッドに対してスレッドの識別番号を与えたい
            Dim i As Integer = e.Argument
    
            Debug.Print(i)
    
            Debug.Print(String.Format("({0})が開始されました。", i))
            Debug.Print(String.Format("({0})が終了しました。", i))
            GC.Collect()
        End Sub
    
        Private Sub BW_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
        End Sub
    
        '処理終了
        Private Sub BW_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
            Debug.Print("BW_RunWorkerCompleted")
        End Sub
    End Class
    参考サイト: https://stackoverflow.com/questions/4807152/sending-arguments-to-background-worker
    • 回答としてマーク huahi11112 2018年1月18日 2:55
    2018年1月18日 2:21
  •  Dim i As Integer = e.Argumentなるほど!こんな方法があるのですね。

    非常に役に立ちました。

    kenjinoteさん、今回はどうもありがとうございました!

    2018年1月18日 2:57