0

谁能解释为什么以下代码在某些 Win7 PC 上有效,但在某些 PC 上我得到一个 MissingMethodException 并且永远不会调用 Timer.Elapsed 事件。

Private Sub _timer2_Elapsed(ByVal sender As Object, ByVal e As System.EventArgs) Handles _timer2.Elapsed
    _timer2.Enabled = False
    Dispatcher.Invoke(Sub()
                          HandleSingleKeyPress(-1)
                      End Sub)
End Sub

经过一番调查,我发现以下代码效果更好:-

Public Delegate Sub InvokedSubDelegate()
Private Sub _timer2_Elapsed(ByVal sender As Object, ByVal e As System.EventArgs) Handles _timer2.Elapsed
    _timer2.Enabled = False
    Dispatcher.Invoke(New InvokedSubDelegate(Sub()
                                                 HandleSingleKeyPress(-1)
                                             End Sub))
End Sub

不知道为什么第一种方法有时只有效,但希望该解决方案可以帮助其他有类似问题的人。

杰瑞

4

1 回答 1

2

听起来您似乎还没有接近确定真正的问题。该片段中肯定不止一个。

MissingMethodException 是一个 DLL 地狱问题。换句话说,您正在使用旧版本的程序集运行代码,该程序集还没有您尝试调用的方法。通过在部署程序集时多加注意,您可以避免 DLL Hell。并且通过虔诚地增加 [AssemblyVersion]。在使用 Project + Properties、Application 选项卡、Assembly Information 按钮完成的 VB.NET IDE 中。这确实解释了为什么第二个片段似乎没有这个问题,你只是不太可能使用旧版本的程序集运行。

当您使用 System.Timers.Timer 类时,这确实会很糟糕。这是一门讨厌的课。在一个非常不寻常的判断失误中,Microsoft 决定吞下Elapsed 事件处理程序中引发的所有异常。这解释了为什么计时器似乎停止工作,当异常中止代码时,它不会按照您的要求执行。喜欢 System.Threading.Timer 类,它不会吞下异常。或者总是在 Elapsed 处理程序中使用 try/catch,尽管很难弄清楚当你捕获时要做什么。Environment.Exit() 是明智的。

但最重要的是,您只是使用了完全错误的计时器。当您使用 Dispatcher.Begin/Invoke() 再次使其同步时,使用异步是没有意义的。只需使用 DispatcherTimer 代替。得到完全相同的结果,减去肮脏和开销。并且需要问这个问题。

于 2014-02-18T17:16:55.967 回答