VB.Net:计时器和事件处理程序相互影响

问题描述 投票:3回答:1

在Windows窗体中,我有:

  • 定时器tmrBackup,定期执行本地数据库的备份
  • 当FileSystemWatcher检测到给定目录中的新文件时,引发过程ImportNewFile的事件过程。

只要它们不相互干扰,它们中的每一个都能完美地工作。

我尝试通过在备份启动时停止FileSystemWatcher来防止这种情况,并在完成备份时再次启动它。

另一方面,我在ImportNewFile的开头设置了tmrBackup.Stop(),然后将文件的内容转换为本地数据库中的记录。在ImportNewFile结束时,我再次设置tmrBackup.Start()。但计时器永远不会再次启动,因此这似乎不是一种可行的方法。

但是,当我没有设置tmrBackup.Stop()时,我在调试期间看到一个奇怪的行为:当ImportNewFile中的某个定时器触发时,似乎两个例程都在并行运行:执行tmrBackup例程中的一行,然后执行VB .Net跳回到ImportNewFile一行,然后回到计时器等。

问题:使用两个对象的正确方法是什么,每个对象都可以在处理另一个事件时触发?谢谢!

vb.net event-handling
1个回答
4
投票

在这种情况下,典型的解决方案是将SyncLock块放在每个事件处理程序中的必要代码周围,并让它们同步到同一个对象,而不是试图暂时禁用相反的计时器,这是很好的并且不能保证工作。 。

当代码被SyncLock包围时,执行将停止并等待,然后进入SyncLock块,直到任何其他相关的SyncLock代码完成。关联它们的方法是为SyncLock语句提供一个要同步的对象。如果两个SyncLock块同步到同一个对象,那么这两个代码块都不会同时运行。

换句话说,如果两个代码块同时被调用,那么先从哪个开始获胜,并且它会一直运行直到它完成,而第二个代码块只是等待开始执行直到完成第一个代码块。

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
© www.soinside.com 2019 - 2024. All rights reserved.