トップ回答者
BackgroundWorker.DoWorkメソッドに固有の情報を与えたい

質問
-
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
回答
-
スレッドに何番目のスレッドかを表す整数値を渡したいということですね。
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
すべての返信
-
スレッドに何番目のスレッドかを表す整数値を渡したいということですね。
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