VB.NET 中事件的 GetInvocationList
我正在嘗試通過遵循 WCF 應用程序範例(來自 Sacha Barber)來學習一些 WCF 原則。
現在我想將以下函式轉換為 VB.NET
private void BroadcastMessage(ChatEventArgs e) { ChatEventHandler temp = ChatEvent; if (temp != null) { foreach (ChatEventHandler handler in temp.GetInvocationList()) { handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null); } } }但是我有一些問題,因為編譯器不接受以下程式碼
Private Sub BroadcastMessage(ByVal e As ChatEventArgs) Dim handlers As EventHandler(Of ChatEventArgs) = ChatEvent If handlers IsNot Nothing Then For Each handler As EventHandler(Of ChatEventArgs) In handlers.GetInvocationList() handler.BeginInvoke(Me, e, New AsyncCallback(AddressOf EndAsync), Nothing) Next End If End Sub它說
Public Shared Event ChatEvent(sender As Object, e As ChatEventArgs)‘是一個事件,不能直接呼叫
說到重點,在 VB.NET 中是否有可能以其他方式將處理程序連結到某個事件?
使用 ChatEventEvent(或EventName事件)
它不會出現在智能感知中,但它的成員會。
VB.NET 在幕後創建一個變數,以隱藏編碼器的複雜性……
這僅在聲明事件(或其後代)的類中可用
您可能試圖在聲明
ChatEvent事件的類的後代類中編寫此程式碼。這是無法做到的,因為事件只能在聲明它們的類中被視為變數(包括呼叫它們)。這是因為event關鍵字實際上向編譯器表明它需要執行一些幕後轉換。發生什麼了
考慮這個聲明:
Public Event MyEvent as EventHandler很簡單,對吧?然而,這實際上做了什麼(你只是看不到它)
Private compilerGeneratedName as EventHandler Public Event MyEvent as EventHandler AddHandler(ByVal value as EventHandler) compilerGeneratedName += value End AddHandler RemoveHandler(ByVal value as EventHandler) compilerGeneratedName -= value End RemoveHandler RaiseEvent(ByVal sender as Object, ByVal e as EventArgs) compilerGeneratedName.Invoke(sender, e) End RaiseEvent End Event當您呼叫事件時:
RaiseEvent MyEvent(Me, EventArgs.Emtpy)它實際上呼叫了
RaiseEvent塊中的程式碼。編輯
如果 VB.NET 中的事件在任何地方都不能被視為變數(它們可以被視為 C# 中聲明類中的變數,這就是 C# 範例編譯的原因),那麼您必須自己顯式地實現該事件。有關如何執行此操作的更多資訊,請參閱Event 語句上的 MSDN 頁面。長話短說,您將需要某種方式來儲存多個事件處理程序(或使用單個事件處理程序以及
GetInvocationList,就像您現在嘗試做的那樣)。在您的AddHandler和RemoveHandler程式碼塊中,您將(分別)添加到事件處理程序列表和從事件處理程序列表中刪除。你可以使用這樣的東西:
Private myEventList as New List(Of EventHandler) Public Custom Event MyEvent as EventHandler AddHandler(ByVal value as EventHandler) myEventList.Add(value) End AddHandler RemoveHandler(ByVal value as EventHandler) myEventList.Remove(value) End RemoveHandler RaiseEvent(ByVal sender as Object, ByVal e as EventArgs) For Each evt in myEventList evt.BeginInvoke(sender, e, New AsyncCallback(AddressOf EndAsync), Nothing) Next EndRaiseEvent End Event所以現在,如果你打電話
RaiseEvent MyEvent(Me, EventArgs.Emtpy)它將以您期望的方式引發事件。