asp.net global synclock object

1.8k views Asked by At

is there a way in asp.net to make sure that a certain threaded sub is not run twice concurrently, no matter what?

the code i have now is

Public Class CheckClass
ReadOnly Property CheckSessionsLock As Object
    Get
        If HttpRuntime.Cache("CheckSessionsLock") Is Nothing Then HttpRuntime.Cache("CheckSessionsLock") = New Object
        Return HttpRuntime.Cache("CheckSessionsLock")
    End Get
End Property
Sub TryThreads()
    Dim thread = New Thread(AddressOf TryLock)
    thread.Priority = ThreadPriority.Lowest
    thread.Start()
End Sub
Sub TryLock()
    SyncLock CheckSessionsLock
        DoTrace("entered locker")
        For x = 0 To 10000
        Next
        DoTrace("exiting locker")
    End SyncLock
    DoTrace("exited locker")
End Sub
End Class

if i run this code on every page then several times the code overlaps. the DoTrace function in the code simply writes the message to a table.

the messages in the table should appear in order (entered,exiting,exited) again and again, but in reality, they don't. i get like entered, exiting,entered,exited,exiting...

this means that the synclock is not complete. is that true?

if so, how can we implement a complete synclock on a block of code, across requests and across sessions?

EDIT: i need this lock, as the real code will be sending emails, according to a list of mailing types in a db. after each mailing type is sent, its marked, then it continues with the next mailing. i cant have in middle of processing, another thread should see this mailing as unprocessed.

please advise

2

There are 2 answers

6
Matthew Steeples On BEST ANSWER

Rather than using the HttpRuntime Cache have you considered using a static variable?

Just as a note (it might be helpful to explain why you want this functionality) your website is not going to be very scalable if this can only be run once at a time.

0
Hans Kesting On

In C# (sorry, don't know VB syntax) I use this:

private static readonly object Padlock = new object();
  • It's a field, not a property,
  • It's static (in VB, that's "shared" if I'm not mistaken) so it's the same throughout the entire application
  • It's initialised once as soon as you use this class, not when you explicitly use the field.

With your property/cache version, you could have two threads trying to get the lock-object and each creating a different one:

  • Thread 1 checks the cache and doesn't find the object
  • Thread 1 is parked
  • Thread 2 checks the cache, doesn't find the object
  • Thread 2 creates the object and caches it, retrieves it again and returns from the property
  • Thread 1 resumes
  • Thread 1 creates a new object and caches it, retrieves it again and returns a different lock object than thread 2 uses
  • Any further threads will use the lock object of thread 1