2010-11-29 77 views
26

我有以下的代碼,其中SprintServiceClient是一個WCF服務 -刪除匿名事件處理

public class OnlineService 
{ 
    private SprintServiceClient _client; 
    public OnlineService() 
    { 
     _client = new SprintServiceClient(); 
    } 

    public void AddMemberToTeam(MemberModel user, int projectId, Action<int> callback) 
    { 
     _client.AddMemberToTeamCompleted += (s, e) => callback(e.Result); 
     _client.AddMemberToTeamAsync(user.ToUser(), projectId); 
    } 
} 

問題的引用,每次AddMemberToTeam被稱爲它增加了一個回調client.AddMemberToTeamCompleted

即第一次AddMemberToTeam被稱爲回調被調用一次,第二次AddMemberToTeam被稱爲回調被稱爲兩次等。

一旦事件處理程序被調用或使用另一個接收回調的方法,是否有任何方法從AddMemberToTeamCompleted中刪除事件處理程序?

+0

要刪除它,你需要一個參考。假設「AddMemberToTeamCompleted」是用'event'關鍵字定義的(只留下 - =和+ =操作符),你必須用委託實例維護一個變量。第一次創建並添加它,下次不添加,在關閉時刪除。 – 2010-11-29 13:00:09

+1

[在C#中取消訂閱匿名方法]的可能的重複(http://stackoverflow.com/questions/183367/unsubscribe-anonymous-method-in-c-sharp) – nawfal 2013-07-22 12:16:34

回答

53

您可以參考您的匿名方法從自身內部,只要你分配一個委託給一個變量第一:

EventHandler<SomeEventArgs> handler = null; 
handler = (s, e) => 
    { 
     _client.AddMemberToTeamCompleted -= handler; 
     callback(e.Result); 
    }; 

_client.AddMemberToTeamCompleted += handler; 

請注意,您需要聲明變量並將其單獨分配,否則當您在方法體內使用它時,編譯器會認爲它未初始化。

+0

完美的作品,謝謝 – 2010-11-29 14:09:08

2

沒有也沒辦法,

Apparantly蒂姆和Marc有另一種很好的解決方案

但你永遠只是他們的名字,並做此方法命名的事件處理程序的-=;)

猜你的事件:

_client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted; 

public void OnAddMemberToTeamCompleted(object sender, EventArgs args) 
{ 
    _client.AddMemberToTeamCompleted -= OnAddMemberToTeamCompleted; 
    callback(e.Result) 
} 

下一個問題是在偵聽器中獲取此回調。也許把它放在一個屬性,EventArgs的(但感覺有點髒,我同意)

18

製作自我取消訂閱事件處理程序的訣竅是捕獲處理程序本身,以便您可以在-=中使用它。有一個聲明明確賦值,雖然;所以我們不能這樣做:

EventHandler handler = (s, e) => { 
    callback(e.Result); 
    _client.AddMemberToTeamCompleted -= handler; // <===== not yet defined  
}; 

所以不是我們初始化null第一,所以聲明是使用,它有一個已知值(null)第一次使用前:

EventHandler handler = null; 
handler = (s, e) => { 
    callback(e.Result); 
    _client.AddMemberToTeamCompleted -= handler;   
}; 
_client.AddMemberToTeamCompleted += handler;