Многопоточность asp.net с синхронизацией

У меня есть тестовый код, который я запускаю при каждой загрузке страницы на моем сайте 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 "выходят" и т. д., что означает, что многопоточность работает нормально, но не синхронизирован ли это правильно?

и как это можно исправить? реальный код будет добавлять записи в базу данных и может вызываться с нескольких страниц разных сеансов, но один и тот же код не должен запускаться дважды одновременно

я ценю помощь 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, потому что при использовании стандартного свойства на одной странице код работает на 100%.

так как я могу убедиться, что 2 потока, даже из совершенно разных сессий, никогда не запускают trylock одновременно?

спасибо всем за помощь

1 ответ

Вы создаете новый экземпляр объекта, когда TryLock метод вызывается и используется для блокировки. Если вы хотите взаимного исключения между двумя потоками, вам нужно использовать общий экземпляр объекта для блокировки, например, статический член вашего класса или параметр, который вы передаете в оба потока.

Другие вопросы по тегам