2010-11-29 80 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;