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

3
在一个Windows表单中,我有:
  • 定时器tmrBackup 定期备份本地数据库
  • 当FileSystemWatcher检测到给定目录中的新文件时,引发过程ImportNewFile的事件过程。
只要它们不相互干扰,每个都能完美地工作。
我试图通过在备份开始时停止FileSystemWatcher,并在完成后重新启动它来防止这种情况发生。
另一方面,在ImportNewFile 的开头,我设置了tmrBackup.Stop(),然后将文件内容转换为本地数据库中的记录。在ImportNewFile的结尾处,我再次设置tmrBackup.Start()。但是计时器永远不会重新启动,因此似乎这不是可行的方法。
然而,如果我不设置tmrBackup.Stop(),则在调试期间会看到奇怪的行为:当ImportNewFile中某个位置触发计时器时,似乎两个例程都在并行运行:执行tmrBackup例程中的一行,然后VB.Net跳回ImportNewFile一行,然后返回计时器等。
问题:如何正确处理两个对象,使每个对象在处理另一个对象的事件时都能触发?谢谢!
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

2
哇,这个方法很好用!谢谢!我之前从没听说过 SyncLock。如果你不知道它的名字,想要搜索它也很困难。:o) - Anumi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接