2012-04-12 64 views
1

我搜索過有關使用關鍵字的Handles代替AddHandler的,在VB.NET的差別,但我無法解釋爲什麼這個代碼不工作..差Vs的AddHandler

Imports System.Threading 
Public Class MyClass_EventArgs 
    Inherits System.EventArgs 
End Class 

Public Class MyClass 
    Public Event MainThreadFinished(ByVal sender As Object, ByVal e As MyClass_EventArgs) 
    Private WithEvents MyEvents As MyClass 
    Private trd As Thread 
    Public Sub New() 
     'AddHandler MainThreadFinished, AddressOf Me.MyEvents_ThreadFinished 
     trd = New Thread(AddressOf mainThread) 
     trd.IsBackground = True 
     trd.Start() 
     RaiseEvent MainThreadFinished(Me, Nothing) 
    End Sub 
    Protected Overrides Sub Finalize() 
     trd.Abort() 
    End Sub 
    Protected Sub MyEvents_ThreadFinished(ByVal sender As Object, ByVal e As MyClass_EventArgs) _ 
       Handles MyEvents.MainThreadFinished 
     MessageBox.Show("AAA") 
    End Sub 
    Private Sub mainThread() 
     RaiseEvent MainThreadFinished(Me, Nothing) 
    End Sub 
End Class 

那麼,這個代碼永遠不會響應事件,但如果我取消了跟隨着行,代碼工作和消息框出現...

'AddHandler MainThreadFinished, AddressOf Me.MyEvents_ThreadFinished 

爲什麼會出現這種情況?

+0

您正試圖聆聽您*自己的*事件。沒有任何意義,一些其他*班會對你的活動感興趣。 vb編譯器只實現Handles的有意識的使用。如果需要這種模式,請使用虛擬方法。 – 2012-04-12 13:31:31

+0

是的,你是對的,這不是一個好的實現,但我寫這個測試事件系統。 – Katte 2012-04-12 14:03:37

回答

4

它看起來像你做了一個很好的發現!每微軟的文檔,RaiseEvent Statement

非共享事件不應該在聲明它們的 類的構造函數內提出。雖然這些事件不會導致運行時錯誤,但它們可能無法被關聯事件 處理程序捕獲。如果您需要 從構造函數中引發事件,請使用Shared修飾符來創建共享事件。

換句話說,微軟說你不應該做你正在做的事 - 如果你必須的話,要使用共享事件。

在翻閱其他資料時,我會說AddHandlerHandles之間的區別是語法糖的問題。您可能想了解如何使用C#完成事件以獲取更多信息(例如,在C# Events)。 HandlesWithEvents結合使用,作爲類的一個實例自動訂閱事件的方式(在C#中使用+=明確地完成,在VB.NET中使用AddHander明確完成)。

看起來你的顯式AddHandler確保事件連接在RaiseEvent之前,並且它按照你的意願工作。我只能猜測,如果沒有這些,那些事件連接還沒有完成 - 也就是說,它不起作用,因爲編譯器在後臺插入執行AddHandler的代碼的代碼,無論編譯器作者是什麼樣的設計模式視爲適當。看起來設計師很清楚這種可能的後果,因爲他們對此有所警告。

+0

嘿,你知道有什麼好的資源可以找到像這樣的好內容嗎?我發現很難理解VB.net中的事件,我必須使用WithEvents,RaiseEvents,AddHandler和其他東西。我試圖做的是通過點擊一個按鈕將數據從一個用戶控件的文本框傳輸到另一個用戶控件,我找不到任何可以證明這一點的教程。 – Wax 2016-10-03 11:38:32

+0

@Carnal:事件只是實現「回調」(https://en.wikipedia.org/wiki/Callback_(computer_programming))的另一種方式。這是一種讓您的課程與其他課程互動的方式。你可以在你的類中定義事件,並且在你的類的關鍵或有趣的地方,你的代碼使用'RaiseEvent'來讓其他類響應那些關鍵或有趣的時刻。其他類會自動('WithEvents'和'Handles')或顯式地('AddHandler')訂閱您的類中定義的任何事件。 – rskar 2016-10-06 17:38:14

+0

@Carnal:訂閱的意思是這樣的:其他一些類將'Delegate'(.NET的等價函數指針)傳遞給您的類,以便在您的類中定義一個特定的Event;這個代表將會在另一個類中的某個'Function'或'Sub'中。當你的類執行'RaiseEvent'事件時,它會調用每個由其他類傳入的'Delegate'。當有多個代表時,它會依次調用每個代表,每次一個(按照任意順序)。當沒有代表時,沒有任何反應。 – rskar 2016-10-06 17:45:17