我有以下vb.net代码,我不确定这里是否存在竞争条件。
在我的测试中,我没有看到竞争条件的证据。
Public Class Worker
Private _List As New List(Of clsTag)
' assume that we added tag objects to list defined above ....
Public Sub Main()
Dim tagCol As IEnumerable = _List
Parallel.ForEach(tagCol.Cast(Of Object)(), Sub(TagObj As clsTag)
TagObj.CheckLogicValue()
End Sub)
End Sub
End Class
Public Class clsTag
Public Sub CheckLogicValue()
...
glbObject.CalcSomething(Me)
...
End Sub
End Class
Public Class SharedObject
Public Function CalcSomething(ByRef objTag As clsTag) As Decimal
' Do some calculation based on objTag and also modify objTag status here!
End Function
End Class
其中glbObject
是全局对象,SharedObject
类的实例,函数CalcSomething
获取TagObj ByRef
并修改此对象。
安全吗?
关于CalcSomething
的作用:
_List
)并从中读取(不做任何修改)。根据计算结果(也是函数返回的内容),正在更新tagObject
传递的ByRef
字段,所以它是这样的:
Public Class SharedObject
Public Function CalcSomething(ByRef objTag As clsTag) As Decimal
' Do some calculation based on objTag and also modify objTag status here!
if (...) then
objTag.ItemBroken = False
EndIf
End Function
End Class
答案 0 :(得分:0)
CalcSomething
中的代码修改(或甚至使用)某些状态变量而不是传递的参数中包含的状态变量,那么您确实有明确的竞争条件。 即使您不访问参数以外的任何内容,如果您要更改它,如果在集合中使用两次相同的对象,仍然可能会出现竞争条件,例如
Dim _tag = New clsTag With {...}
_List.Add(_tag);
_List.Add(_tag);
请注意,除非我们确切知道代码正在做什么,否则无法给出明确的答案
如果仅读取全局状态,并且您绝对确定在执行该方法期间不会更改该状态,那么您应该避免全局值竞争条件。
此外,如果.ItemBroken
(或任何其他设置的字段/属性)未在计算本身中使用,但仅作为某些(可重复)检查的结果而设置,则可以合理地确定您赢了没有竞争条件。
另一方面,Paralel.For
不会神奇地加快处理速度,并且会使代码更难理解。你确定一个简单的,顺序的Foreach
不会那么快,而且更容易理解和调试吗?
For Each TagObj As clsTag In tagCol
TagObj.CheckLogicValue()
Next