删除匿名事件处理程序

时间:2010-11-29 12:56:17

标签: c# wcf

我有以下代码,其中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,调用回调两次,等等。

有没有办法在调用eventhandler后从AddMemberToTeamCompleted中删除eventhandler,或者使用另一个接受回调的方法?

3 个答案:

答案 0 :(得分:53)

只要您首先将委托分配给变量,就可以从内部引用您的匿名方法:

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

_client.AddMemberToTeamCompleted += handler;

请注意,您需要声明变量并单独指定它,否则当您在方法体内使用它时,编译器会认为它未初始化。

答案 1 :(得分: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;

答案 2 :(得分:2)

没有办法,

显然Tim和Marc有另一个不错的解决方案

但是你总是可以命名它们,并在这个方法上对命名的eventhandler执行-=;)

猜猜你的活动:

_client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted;

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

下一个问题是在你的监听器中获得这个回调。也许把它放在EventArgs的一个属性上(但感觉有点脏,我同意)