2014-02-18 36 views
0

任何人都可以解釋爲什麼下面的代碼在一些Win7的PC上工作,但在一些我得到一個MissingMethodException和Timer.Elapsed事件永遠不會被調用。正確的方式調用Dispatcher.Invoke

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

回答

2

這聽起來並不像你接近確定真正的問題。這段代碼中肯定有不止一個。

MissingMethodException是一個DLL地獄問題。換句話說,您正在使用程序集的舊版本運行您的代碼,該代碼還沒有您嘗試調用的方法。在部署程序集時,請注意避免DLL地獄。並且通過宗教地增加[AssemblyVersion]。在使用Project + Properties,Application選項卡,Assembly Information按鈕完成的VB.NET IDE中。這可以解釋爲什麼第二個代碼段不是似乎有這個問題,您不太可能使用該舊版本的程序集運行。

當您使用System.Timers.Timer類時,這確實會很糟糕。這是一個討厭的類。在非常不合時宜的判斷中,微軟決定吞下在Elapsed事件處理程序中引發的所有異常。這就解釋了爲什麼計時器似乎停止工作,當異常中止代碼時,它不會執行你要求它執行的操作。贊成System.Threading.Timer類,它不會吞下異常。或總是在Elapsed處理程序中使用try/catch,儘管在捕捉時很難弄清楚該怎麼做。 Environment.Exit()是明智的。

但最重要的是,你只是使用完全錯誤的計時器。使用Dispatcher.Begin/Invoke()使其再次同步時,使用異步程序沒有意義。只需使用DispatcherTimer。獲得完全相同的結果,減去糟糕和開銷。而且需要問這個問題。

+0

我最初使用了dispatcher.timer,但是我試圖通過測量點擊間隔來檢測雙擊,這是當然的。在閱讀其他帖子中的評論之後,我也嘗試了threading.timer。我仍然有同樣的例外。 – Jerry

+1

使用System.Timers.Timer來測量點擊間隔是毫無意義的。你當然使用鼠標事件,它告訴你鼠標被點擊。還有一個準確的間隔計時器,可以查看Stopwatch需要多長時間。在你的問題中陳述你的目標非常重要。 –

+0

我的目標是理解爲什麼在代理中包裝llambda函數會造成巨大差異,但僅限於某些系統。我接受我可以使用StopWatch並避免使用Invoke,但這只是解決問題。我不認爲這與我使用計時器有任何關係。我也有這樣的代碼: - – Jerry