正确的方法来调用Dispatcher.Invoke

时间:2014-02-18 15:50:26

标签: wpf vb.net invoke dispatcher missingmethodexception

任何人都可以解释为什么下面的代码可以在某些Win7 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

不确定为什么第一种方法有时只能起作用,但希望解决方案可以帮助其他有类似问题的方法。

杰里

1 个答案:

答案 0 :(得分:2)

听起来你并没有发现真正的问题。该片段当然不止一个。

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

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

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