带有同步锁的 ASP.NET 多线程
我有一些测试代码,在我的 asp.net 网站中每次加载页面时都会运行,
这是“dotrace”代码
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
,只需将一条记录添加到数据库中的日志表中
,现在正确的结果是我应该有数据库中的条目按顺序“进入”、“退出”、“退出”,
但实际上当我查看数据库时,我看到前 2 个“进入”,然后是 2 个“退出”等。 这意味着多线程工作正常,但同步锁工作正常 这是正确的吗?
如何解决这个问题? 真正的代码将向数据库添加记录,并且可能从不同会话的多个页面调用,但是相同的代码不能同时运行两次,
我非常感谢任何人的帮助,
非常感谢!
编辑:
为了回应 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,因为当使用标准属性时,在一页上,代码可以 100% 工作。
那么我如何确保两个线程,即使来自完全不同的会话,也不会同时运行 trylock ?
谢谢大家的帮助
i have some test code which i run at every load of a page in my asp.net website
this is the code
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
the "dotrace" simply add a record to a log table in the db
now the right result would be that i should have the entries in the db in order "entered","exiting","exited"
but actually when i look in the db i see first 2 "entered" then 2 "exiting" etc.
meaning that the multithreading is working ok, but not the synclock
is that correct?
and how can this be fixed?
the real code will be adding records to the db and might be called from several pages of different sessions, but the same code must not run twice concurrently
i do appreciate anybodys help
thank you very much!!!
EDIT:
in response to Sashas wonderful post i changed my code to a class (it was in a module) and now it looks like this:
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
now it works 80-90% of the time.
on page load i have:
Dim cc = New CheckClass
cc.TryThreads()
if i open multiple pages at once, they still clash some times. but if i'm correct, the issue is now not with the synclock as much as with the httpruntime.cache, because when using a standard property, on one page, the code works 100%.
so how can i make sure that 2 threads, even from totally different sessions never run the trylock simultaneously?
thank you all for helping out
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当调用
TryLock
方法时,您将创建一个新的对象实例,并将其用于锁定。如果您希望两个线程之间互斥,则需要使用公共对象实例进行锁定,例如类的静态成员或传递给两个线程的参数。You are creating a new object instance when the
TryLock
method is called, and use that for locking. If you want mutual exclusion between the two threads, you need to use a common object instance for locking, e.g. a static member of your class or a parameter that you pass to both threads.