Reputation: 45
I have a loop that creates several threads as such:
SomeClass..
Dim someNumber As Integer = 0
Dim somethingElse As Integer = 10
Dim myThread(500) As System.Threading.Thread
For i As Integer = 0 To 500
someNumber += 1
somethingElse += 10
myThread(i) = New Thread(Sub() myThreadFunction(someNumber, somethingElse))
myThread(i).Start()
Next
For j As Integer = 0 To 500
myThread(j).Join()
Next
Sub myThreadFunction(ByVal someNumber As Integer, ByRef somethingElse As Integer)
DoStuff
End Sub
Now my problem is that sometimes I get the wrong values passed to myThreadFunction, usually the value that's supposed to be passed in the next iteration of the loop.
Am I doing something wrong, and is there a better way to do this?
Upvotes: 3
Views: 2372
Reputation: 564451
This is due to the lambda closing over your variables in the wrong scope. Eric Lippert describes this problem in detail in Closing over the loop variable considered harmful.
To make this work, you need to introduce a temporary variable in the proper scope:
For i As Integer = 0 To 500
someNumber += 1
somethingElse += 10
' Make some locally scoped variables
Dim temp1 As Integer = someNumber
Dim temp2 As Integer = somethingElse
' Use the temporaries
myThread(i) = New Thread(Sub() myThreadFunction(temp1, temp2))
myThread(i).Start()
Next
On a separate note: I would recommend also considering using the ThreadPool or the Task Parallel Library instead of manually creating threads. This is, in general, a better approach for most scenarios.
Upvotes: 4