我有一个循环,可以创建几个线程:
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
现在我的问题是,有时我得到传递给myThreadFunction的错误值,通常是在循环的下一次迭代中应该传递的值。
我做错了什么,有更好的方法吗?
答案 0 :(得分:4)
这是因为lambda在错误的范围内关闭了变量。 Eric Lippert在Closing over the loop variable considered harmful中详细描述了这个问题。
要使其工作,您需要在适当的范围内引入临时变量:
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
另请注意:我建议您还考虑使用ThreadPool或Task Parallel Library而不是手动创建线程。对于大多数情况,这通常是更好的方法。