带有同步锁的 ASP.NET 多线程

发布于 2024-10-15 06:06:55 字数 2104 浏览 4 评论 0原文

我有一些测试代码,在我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生活了然无味 2024-10-22 06:06:55

当调用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文