многопоточность asp.net с синхронизацией - PullRequest
1 голос
/ 31 января 2011

У меня есть тестовый код, который я запускаю при каждой загрузке страницы на моем сайте 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 help

большое спасибомного !!!

РЕДАКТИРОВАТЬ:

в ответ на замечательный пост Саша, я изменил свой код на класс (это было в модуле), и теперь это выглядит так:

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 потока, даже из совершенно разных сессий, никогда не запускают попытку одновременно?

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

1 Ответ

2 голосов
/ 31 января 2011

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

...