2010-01-29 34 views
7

我想通過遵循一個WCF應用程序(來自Sacha Barber)的示例來學習一些WCF原則。VB.NET中事件的GetInvocationList

現在,我想下面的函數轉換成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 

它說

公共共享事件ChatEvent(發件人 作爲Object,e As ChatEventArgs)'是 事件,並不能直接

稱爲來到點,是那麼VB.NET可能獲得與某一事件在一些其他的方式處理?

回答

7

使用ChatEventEvent(或事件名稱事件)

它不會顯示在IntelliSense,但它的成員。

VB.NET創建幕後的變量,隱藏從編碼器複雜...

這是隻在聲明事件的類(或者它的後代)

+0

請記住,您在課堂上使用的是未經證實的成員,並且(除非我錯了),此命名策略在將來的編譯器版本中不保證保持不變。 – 2010-02-01 13:58:09

+0

@亞當 - 是的,沒有記錄,據我所知,但我看不到他們改變它,除非他們有理由或至少提供替代方案。無論如何,這是您目前唯一可以做到的方式,而無需像您自己的例子那樣自行處理所有事件。如果他們改變它,你的工作仍然會繼續,但我寧願保存那些可能會改變的工作。 – 2010-02-01 19:25:45

5

您可能試圖將這些代碼寫入聲明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#示例編譯變量)那麼你必須自己明確地實施這個事件。有關如何做到這一點的更多信息,請參閱MSDN page on the Event statement。長話短說,你會想要一些方法來存儲多個事件處理程序(或者使用一個事件處理程序以及GetInvocationList,正如你現在要做的那樣)。在您的AddHandlerRemoveHandler代碼塊中,您將分別添加到事件處理程序和從事件處理程序列表中刪除。

你可以使用這樣的事情:

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) 

這將提高在你期待的時尚事件。

+0

謝謝爲了答案,但我不認爲是我的情況。 我的課程叫做ChatService,它聲明瞭共享事件ChatEvent和Sub BroadcastMessage,我試圖獲得ChatEvent的InvocationList。 – Drake 2010-01-29 13:56:39

+0

@marco:在上面的第一個例子中,看看我的編輯是否更有幫助 – 2010-01-29 14:14:37

+1

,在這種情況下,compilerGeneratedName是* always *事件名稱,後跟單詞「Event」,因此是ChatEventEvent。 – 2010-01-29 22:49:50