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