调用Dispatcher.Invoke的正确方法



有人能解释为什么下面的代码在某些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

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

Jerry

听起来你还没有发现真正的问题。这个片段中肯定不止一个。

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

当您使用System.Timers.Timer类时,结果确实很糟糕。这是一个令人讨厌的类。在一次极不寻常的判断失误中,微软决定吞下Elapsed事件处理程序中引发的所有异常。这就解释了为什么计时器似乎停止工作,当异常中止代码时,它不会执行您要求它执行的操作。偏爱System.Threading.Timer类,它不接受异常。或者总是在Elapsed处理程序中使用try/catch,尽管很难弄清楚捕获时该怎么办。Environment.Exit()是明智的。

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

最新更新