1

i have some test code which i run at every load of a page in my asp.net website

this is the code

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

the "dotrace" simply add a record to a log table in the db

now the right result would be that i should have the entries in the db in order "entered","exiting","exited"

but actually when i look in the db i see first 2 "entered" then 2 "exiting" etc. meaning that the multithreading is working ok, but not the synclock is that correct?

and how can this be fixed? the real code will be adding records to the db and might be called from several pages of different sessions, but the same code must not run twice concurrently

i do appreciate anybodys help

thank you very much!!!

EDIT:

in response to Sashas wonderful post i changed my code to a class (it was in a module) and now it looks like this:

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

now it works 80-90% of the time. on page load i have:

Dim cc = New CheckClass
    cc.TryThreads()

if i open multiple pages at once, they still clash some times. but if i'm correct, the issue is now not with the synclock as much as with the httpruntime.cache, because when using a standard property, on one page, the code works 100%.

so how can i make sure that 2 threads, even from totally different sessions never run the trylock simultaneously?

thank you all for helping out

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
Yisroel M. Olewski
  • 1,560
  • 3
  • 25
  • 41

1 Answers1

2

You are creating a new object instance when the TryLock method is called, and use that for locking. If you want mutual exclusion between the two threads, you need to use a common object instance for locking, e.g. a static member of your class or a parameter that you pass to both threads.

Sasha Goldshtein
  • 3,499
  • 22
  • 35
  • hi. thanks for your answer, its now much better. but still not 100%. can you please see my edit in the question? thanks a million! – Yisroel M. Olewski Feb 01 '11 at 14:13
  • @Yisman: I believe you are correct, because indeed you need to synchronize access to the cache. If you want to protect something in a completely global manner, use a static class member like I suggested. – Sasha Goldshtein Feb 01 '11 at 16:19
  • if i make a static class member, will it be locked across different browser sessions in asp.net? i think each session runs the code entirely independent from any other session , no? – Yisroel M. Olewski Feb 02 '11 at 08:52
  • I don't know very much about ASP.NET, but I'm pretty sure that as long as you're in the same IIS application pool, you're in the same Application Domain and hence static members are shared. – Sasha Goldshtein Feb 02 '11 at 13:18
  • i tried adding "Shared Property Lock2 As Object" and use that for the synclock. but no, its not working. its even worse than the cache solution i used previously.as far as i know aspx, a shared property of a class is not shared between sessions,or even multiple requests in same session. so i still need a good locking object. any ideas? – Yisroel M. Olewski Feb 03 '11 at 09:33
  • Please quote the code, possibly as a new question or edit your question. I'm not sure we're talking about the same thing. – Sasha Goldshtein Feb 05 '11 at 14:32
  • thanks. i have made a new question here http://stackoverflow.com/questions/4920481/asp-net-global-synclock-object. thank you very much. – Yisroel M. Olewski Feb 07 '11 at 11:00