Yisroel M. Olewski
Yisroel M. Olewski

Reputation: 1628

asp.net global synclock object

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

Upvotes: 0

Views: 1862

Answers (2)

Hans Kesting
Hans Kesting

Reputation: 39284

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

Upvotes: 1

Matthew Steeples
Matthew Steeples

Reputation: 8058

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.

Upvotes: 2

Related Questions