Using FSO to write to text file - avoiding conflicts (AC2007)

AOB

Registered User.
Local time
Today, 18:21
Joined
Sep 26, 2012
Messages
621
Hi guys,

I have a function to write some data to a text file (as an activity log, separate to the live data contained in the DB)

It uses the FileSystemObject.OpenTextFile method and works fine

However, I'm conscious that, although perhaps unlikely, there is the possibility (which is enough for me to worry about it) that multiple users could trigger the function simultaneously, which could cause a conflict when multiple FE's try to write to the same log file at the same time.

So I'm trying to add some code to prevent this from happening, by checking if write-access is available before proceeding.

Below is the piece of code I've added (as yet untested) - just wondering if anybody has any opinion on this method? Is there a better way?

Was considering, as an alternative, looping until the objFile is no longer Nothing, rather than depending on the Err.Number?

Code:
Dim objFSO As Object
Dim objFile As Object
 
On Error GoTo ErrorHandler
...
Set objFSO = CreateObject("Scripting.FileSystemObject")
...
On Error Resume Next
 
Err.Clear
 
Set objFile = objFSO.OpenTextFile(objFolder.Path & "\" & strLogName & ".txt", IIf(blnNewLog, 2, 8), True)
 
If Not Err.Number = 0 Then
    datTimer = Timer
    Do Until Err.Number = 0 Or Timer > DateAdd("s", 60, datTimer)
        Err.Clear
        Pause (1)    [COLOR=seagreen]' Separate function; does what it says on the tin...[/COLOR]
        Set objFile = objFSO.OpenTextFile(objFolder.Path & "\" & strLogName & ".txt", IIf(blnNewLog, 2, 8), True)
    Loop
End If
 
On Error GoTo ErrorHandler
 
If Not Err.Number = 0 Then
    Err.Raise vbObjectError + 1000, , "Error writing to " & strLogName & "log (write-access timeout)"
End If
....
 
Hello again AOB,

Sounds like a good idea checking every so often, I would check in milliseconds rather than in seconds.

If you're really that worried about this concurrency problem then I would create a queue. Each log entry goes into the queue and a delegate function writes the queued items into the file every couple of milliseconds.

This is type of process is ideal in a threaded environment but I'm sure you can work something out.
 
Hi guys,

I have a function to write some data to a text file (as an activity log, separate to the live data contained in the DB)

It uses the FileSystemObject.OpenTextFile method and works fine

However, I'm conscious that, although perhaps unlikely, there is the possibility (which is enough for me to worry about it) that multiple users could trigger the function simultaneously, which could cause a conflict when multiple FE's try to write to the same log file at the same time.

So I'm trying to add some code to prevent this from happening, by checking if write-access is available before proceeding.

Below is the piece of code I've added (as yet untested) - just wondering if anybody has any opinion on this method? Is there a better way?

Was considering, as an alternative, looping until the objFile is no longer Nothing, rather than depending on the Err.Number?

Code:
Dim objFSO As Object
Dim objFile As Object
 
On Error GoTo ErrorHandler
...
Set objFSO = CreateObject("Scripting.FileSystemObject")
...
[COLOR="Magenta"]On Error Resume Next
 
Err.Clear
 
Set objFile = objFSO.OpenTextFile(objFolder.Path & "\" & strLogName & ".txt", IIf(blnNewLog, 2, 8), True)
 
If Not Err.Number = 0 Then
    datTimer = Timer
    Do Until Err.Number = 0 Or Timer > DateAdd("s", 60, datTimer)
        Err.Clear
        Pause (1)    [COLOR=seagreen]' Separate function; does what it says on the tin...[/COLOR]
        Set objFile = objFSO.OpenTextFile(objFolder.Path & "\" & strLogName & ".txt", IIf(blnNewLog, 2, 8), True)
    Loop
End If[/COLOR]
 
On Error GoTo ErrorHandler
 
If Not Err.Number = 0 Then
    Err.Raise vbObjectError + 1000, , "Error writing to " & strLogName & "log (write-access timeout)"
End If
....

Hi,
things you may want to reconsider:
1) datTimer is not defined but if it is single precision (as Timer is), it will cause problems because it does not have the date component. It is questionable here because of the rollover issue.
2) The opening mode of the fso.OpenTextFile uses a test IIf(blnNewLog, 2, 8). This is redundant. ForAppending (8) mode will cover new file as well.
3) the loop looks a bit strange. I would re-write the purple as :
Code:
On Error Resume Next
datTimer = Date()    
Do 
     If Err,Number <> Then Err.Clear
     Pause (x)    [COLOR=seagreen]' Separate function; does what it says on the tin...[/COLOR]
     Set objFile = objFSO.OpenTextFile(objFolder.Path & "\" & strLogName & ".txt", 8, True)
Loop Until Err.Number = 0 Or Date() > DateAdd("s", 60, datTimer)
End If

Best,
Jiri
 
Thank you both for the feedback, much appreciated!
 

Users who are viewing this thread

Back
Top Bottom