带有synclock的asp.net多线程

时间:2011-01-31 13:48:26

标签: asp.net vb.net multithreading synclock

我有一些测试代码,我在我的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?

谢谢大家帮忙

1 个答案:

答案 0 :(得分:2)

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