1

我有一些测试代码,我在我的 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”只是将一条记录添加到数据库中的日志表中

现在正确的结果是我应该在数据库中按顺序“输入”、“退出”、“退出”

但实际上,当我查看数据库时,我看到前 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% 工作。

那么我如何确保 2 个线程,即使来自完全不同的会话,也不会同时运行 trylock?

谢谢大家帮忙

4

1 回答 1

2

当方法被调用时,您正在创建一个新的对象实例TryLock,并将其用于锁定。如果您希望两个线程之间互斥,您需要使用一个公共对象实例进行锁定,例如您的类的静态成员或您传递给两个线程的参数。

于 2011-01-31T14:47:27.190 回答