Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.Net: timer and event handler influence each other

In a Windows form I have:

  • a timer tmrBackup that regularly performs a backup of a local database
  • an event procedure that raises a procedure ImportNewFile when FileSystemWatcher detects a new file in a given directory.

Each of these work perfectly as long as they don't interfere each other.

I try to prevent that by stopping the FileSystemWatcher when a backup starts, and starting it again when it's finished.

On the other hand I set tmrBackup.Stop() in the beginning of ImportNewFile, then the contents of the file are transformed into a record in the local database. At the end of ImportNewFile I set tmrBackup.Start() again. But the timer is never started again, so that seems to be not a viable way.

When I don't set tmrBackup.Stop(), though, I see a strange behavior during debugging: when somewhere in ImportNewFile the timer fires, it seems that both routines are running parallel: one line in the tmrBackup routine is executed, then VB.Net jumps back to ImportNewFile for one line, then back to the timer, etc.

Question: what is a correct method to work with two objects with each being able to fire while the other's event is handled? Thanks!

like image 242
Anumi Avatar asked Mar 28 '26 00:03

Anumi


1 Answers

Rather than attempting to temporarily disable the opposite timer, which is hokey and not guaranteed to work, the typical solution in such cases is to put SyncLock blocks around the necessary code in each of the event handlers, and have them both synchronize to the same object.

When code is surrounded by a SyncLock, execution will stop and wait, before entering the SyncLock block until any other related SyncLock code is finished. The way to relate them is by giving the SyncLock statement an object to synchronize against. If two SyncLock blocks synchronize to the same object, then neither of those two blocks of code will ever be allowed to run simultaneously.

In other words, if both blocks of code get called simultaneously, whichever starts first wins, and it runs through until it's complete, and the second just waits to begin executing until the first one is done.

Public Class SyncLockExample
    Private WithEvents object1 As MyType1
    Private WithEvents object2 As MyType2
    Private syncObj As New Object()

    Private Sub object1_MyEvent1(Object sender, EventArgs e) Handles object1.MyEvent1
        SyncLock syncObject
            ' Do something that can't happen at the same time as object2_MyEvent2
        End SyncLock
    End Sub

    Private Sub object2_MyEvent2(Object sender, EventArgs e) Handles object2.MyEvent2
        SyncLock syncObject
            ' Do something that can't happen at the same time as object1_MyEvent1
        End SyncLock
    End Sub
End Class
like image 126
Steven Doggart Avatar answered Apr 01 '26 08:04

Steven Doggart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!