Link to home
Create AccountLog in
Avatar of PhotoCompManager
PhotoCompManager

asked on

locking files in ASPX

I read and write an XML file from my ASPX app. I have tried to lock the writes with the code below, but it doesn't seem to work.
When the Monitor.tryenter is used, it times out even in the development environment (when there can be no other users)

Is there a better way to lock for writing?
'If Not Monitor.TryEnter("lockPastEnt", 10000) Then
        '    messageToLastResort("UpdatePastEntrant was locked... " & thisEntrant.Email)
        '    Exit Sub
        'End If
        Monitor.Enter("lockPastEnt")
        Try

.... the read/write to update the file goes here
        Finally
            Monitor.Exit("lockPastEnt")
        End Try

Open in new window

Avatar of JustAndrei
JustAndrei
Flag of Belarus image

Try add logging code, in order to make sure that another thread does not lock that.
Avatar of PhotoCompManager
PhotoCompManager

ASKER

I'd have to lock the log, though, wouldn't I?
It does not matter, you just need to close the log file (or flush) after every log message.
I suggest logging, because you wrote "it times out even in the development environment", while I'm not sure it times out at the very first moment. You probably have two threads, and one of them is working too long.
By the way, even knowing that strings are interned, I would create and refer to a global constant string or a static object like this:
static object lockPastEnt = new object(); // sorry for c# syntax, anyway you can get the idea
If Not Monitor.TryEnter(lockPastEnt, 10000)
...
Monitor.Exit(lockPastEnt)
This would prevent vexatious typo errors.
ASKER CERTIFIED SOLUTION
Avatar of JustAndrei
JustAndrei
Flag of Belarus image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Thanks Andrei
Your comments got me onto the right track and I've got some working code with Mutex and Semaphore...
Here's a test form in case anyone else has the same problem and finds this thread!
Imports System.Threading
Public Class Form1
'To test, put two buttons on a form with a text box containing the name of the thing you want to lock (eg a file name)
'Run two copies of the excutable
    Private Sub cmdReadFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReadFile.Click
        Dim semaphore As Semaphore = New Semaphore(32, 32, txtFileName.Text & "_S") ' this locks the file for write only -  32 theads can read simultaneously
        semaphore.WaitOne()
        Try
        MsgBox("Semaphore held for " & txtFileName.Text)
            'read the file or something
        Finally
            semaphore.Release()
        End Try
    End Sub

    Private Sub cmdWriteFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdWriteFile.Click
        Dim semaphore As Semaphore = New Semaphore(32, 32, txtFileName.Text & "_S")
        Dim mutex As Mutex = New Mutex(False, txtFileName.Text & "_M") 'must have a different name from the semaphore
        mutex.WaitOne() ' this prevents anyone else writing
        For i = 1 To 32
            semaphore.WaitOne() 'This prevents anyone else from reading while we write
        Next i
         Try
             MsgBox("Mutex held for " & txtFileName.Text)
             'write the file or something
      Finally
            For i = 1 To 32
                semaphore.Release()
            Next i
            mutex.ReleaseMutex()
        End Try
    End Sub

End Class

Open in new window