-1

I have tried this in VB.2010 and 2019. This is a Windows Desktop app.

It has a FileSystemWatcher create routine that gets control when a file is put into a folder and then processes the file via an invoked function. The invoked function must be synchronous and will have unpredictable problems if multiple instances invoked.

The issue is that once the function (DoMonitorFolder) is invoked the lock is lost and the synclock block will be entered again before the first block completes.

Simplified code is below. With breakpoints I have seen that:

  1. The block is entered before the End Synclock is reached the 2nd time if multiple files are put into the folder. BreakPoints were put after the SyncLock and on the End SyncLock
  2. The RunningFileNowBol is true when entered the 2nd time. It which is set to true in DoFolderMonitor when entered and false before it returns.
  3. If DoFolderMonitor is taken out the Synclock block is only entered after the End Synclock is executed which is what I expected.

So is the a restriction about embedding a function call within the block? Is there an alternative that will synchronize the calling of DoFolderMonitor from FSW.Created?

Private Sub FSW_Created(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FSW.Created
        SyncLock TheProgram ' & "FWS_CREATED"
            If RunningFileNowBol Then   
                iNop = iNop
            Else
                If Not DoFolderMonitor(pFFn:=e.FullPath) Then
                   GoTo ExitFunction
        End If
            End If
        End SyncLock
ExitFunction:
        Return
End Sub
QuickBooksDev
  • 125
  • 1
  • 1
  • 9
  • Is DoFolderMonitor() spawning another thread/task? – Idle_Mind Sep 25 '20 at 13:22
  • No, it is not. But it does do a lot of things. I can try using a skeleton function to test it. – QuickBooksDev Sep 25 '20 at 14:51
  • Well, SyncLock prevents DIFFERENT threads from acquiring the lock. A common "problem" with the FileSystemWatcher is that you can get multiple events firing for a single file action, and I believe all of those events would be fired from the same thread, so what might be happening is that multiple events are causing re-entrancy? I'd throw a `Debug.Print()` line inside the event, and another inside the SyncLock block and see if you are getting multiple hits there... – Idle_Mind Sep 25 '20 at 15:34
  • I ran it and got the following. The ThreadId was the same. using AppDomain.GetCurrentThreadId I copied and pasted 3 files into the folder. – QuickBooksDev Sep 25 '20 at 16:25
  • FWS CREATED Pre SyncLock Fn=SampleBillLarge3.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge3.csv thread=19584 FWS CREATED Pre SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED after SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED Pre SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED after SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED after SyncLock Fn=SampleBillLarge3.csv thread=19584 – QuickBooksDev Sep 25 '20 at 16:25
  • FWS CREATED Pre SyncLock Fn=SampleBillLarge3.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge3.csv thread=19584 FWS CREATED Pre SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED after SyncLock Fn=SampleBillLarge1.csv thread=19584 FWS CREATED Pre SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED after SyncLock Fn=SampleBillLarge2.csv thread=19584 FWS CREATED Pre SyncLock Fn=SampleBillLarge3.csv thread=10920 – QuickBooksDev Sep 25 '20 at 16:32
  • FWS CREATED SyncLock Fn=SampleBillLarge3.csv thread=10920 DoFolderMonitorDummy Entered FWS CREATED Pre SyncLock Fn=SampleBillLarge2.csv thread=10920 FWS CREATED SyncLock Fn=SampleBillLarge2.csv thread=10920 DoFolderMonitorDummy Entered FWS CREATED Pre SyncLock Fn=SampleBillLarge1.csv thread=10920 FWS CREATED SyncLock Fn=SampleBillLarge1.csv thread=10920 DoFolderMonitorDummy Entered – QuickBooksDev Sep 25 '20 at 16:33
  • Public Function DoFolderMonitorDummy(Optional pFFn As String = NIL, Optional ByRef pOutReason As String = NIL) As Boolean Debug.Print("DoFolderMonitorDummy Entered") RunningFileNowBol = True Sleep(4000) RunningFileNowBol = False End Function – QuickBooksDev Sep 25 '20 at 16:33
  • So if the Thread ID is the same, then you are getting into the SyncLock multiple times. You could add a separate boolean variable into the mix to prevent the same thread from running the code again. – Idle_Mind Sep 25 '20 at 16:44
  • One thing I've done in the past is to Start a Timer when the first event rolls in. Set the Interval to something like 3 to 5 seconds. On subsequent events, if the Timer is enabled, stop and restart it. Once all the rapid fire events stop, and the 3 to 5 seconds occurs WITHOUT any new events coming in, the Tick event will fire. Then you can turn off the Timer and run the file handling code. – Idle_Mind Sep 25 '20 at 16:47
  • The dummy routine had a sleep in it. I removed it and the results are different and works as expected. It seems that any system function might be breaking the lock. Is there a good alternative to SyncLock to force the routine to run for just 1 file at a time. – QuickBooksDev Sep 25 '20 at 16:49
  • See my previous two comments. Either use a (1) Boolean Flag, or (2) Timer. – Idle_Mind Sep 25 '20 at 16:53
  • Tried with MuteX and got similar results. The code did not stop on the 2nd MuteX addOne. Tried to put a DoEvents/Sleep loop testing on if a file was being processed prior to the locks but nothing processed. I am at a loss as to what is going on. – QuickBooksDev Sep 26 '20 at 13:42

1 Answers1

0

It seems that System.Windows.Forms.Application.DoEvents() breaks the SyncLock. When DoEvents was not executed then it worked as expected. I am not sure about MuteX but after about 10 hours of trial and error I am done for now.

If anyone has a good alternative that does not break the lock unless released I would appreciated it if you let me know.

QuickBooksDev
  • 125
  • 1
  • 1
  • 9