我有一些测试代码,我在我的asp.net网站的每个页面加载
这是代码
Sub TryThreads()
Dim t1 = New Thread(AddressOf TryLock)
t1.Priority = ThreadPriority.Lowest
t1.Start()
Dim t2 = New Thread(AddressOf TryLock)
t2.Priority = ThreadPriority.Lowest
t2.Start()
End Sub
Sub TryLock()
Dim LockObject = New Object
SyncLock LockObject
DoTrace("entered locker")
For x = 0 To 10000
Next
DoTrace("exiting locker")
End SyncLock
DoTrace("exited locker")
End Sub
“dotrace”只需将记录添加到db
中的日志表中现在正确的结果是我应该按照“已输入”,“退出”,“已退出”的顺序在数据库中输入条目
但实际上当我查看数据库时,我看到前2个“输入”然后2个“退出”等。 这意味着多线程工作正常,但不是synclock 那是对的吗?
如何解决这个问题? 真正的代码将添加记录到数据库,可能会从不同会话的几个页面调用,但相同的代码不能同时运行两次
我非常感谢anybodys帮助
非常感谢!!!
修改
为了回应Sashas精彩的帖子,我将我的代码更改为一个类(它在一个模块中),现在它看起来像这样:
Public Class CheckClass
Property LockObject As Object
Get
If HttpRuntime.Cache("CheckSessionsLock") Is Nothing Then HttpRuntime.Cache("CheckSessionsLock") = New Object
Return HttpRuntime.Cache("CheckSessionsLock")
End Get
Set(ByVal value As Object)
If value Is Nothing Then
HttpRuntime.Cache.Remove("CheckSessionsLock")
Else
HttpRuntime.Cache("CheckSessionsLock") = value
End If
End Set
End Property
Sub TryThreads()
Dim t1 = New Thread(AddressOf TryLock)
t1.Priority = ThreadPriority.Lowest
t1.Start()
Dim t2 = New Thread(AddressOf TryLock)
t2.Priority = ThreadPriority.Lowest
t2.Start()
End Sub
Sub TryLock()
SyncLock LockObject
DoTrace("entered locker")
For x = 0 To 10000
Next
DoTrace("exiting locker")
End SyncLock
DoTrace("exited locker")
End Sub
End Class
现在它的工作时间为80-90%。 在页面加载我有:
Dim cc = New CheckClass
cc.TryThreads()
如果我一次打开多个页面,它们仍然会发生冲突。但是,如果我是正确的,现在问题不在于与httpruntime.cache一样的synclock,因为在一个页面上使用标准属性时,代码可以100%运行。
那么如何确保2个线程,即使是完全不同的会话也不会同时运行trylock?
谢谢大家帮忙
答案 0 :(得分:2)
在调用TryLock
方法时,您正在创建一个新的对象实例,并将其用于锁定。如果要在两个线程之间进行互斥,则需要使用公共对象实例进行锁定,例如:您的类的静态成员或传递给两个线程的参数。