开发者

Removing anonymous event handler

开发者 https://www.devze.com 2023-01-27 15:44 出处:网络
I have the following code where SprintServiceClient is a reference to a WCF Service- public class OnlineService

I have the following code where SprintServiceClient is a reference to a WCF Service-

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

    pub开发者_StackOverflow中文版lic void AddMemberToTeam(MemberModel user, int projectId, Action<int> callback)
    {
        _client.AddMemberToTeamCompleted += (s, e) => callback(e.Result);
        _client.AddMemberToTeamAsync(user.ToUser(), projectId);
    }
}

the problem is that every time AddMemberToTeam is called it adds another callback to client.AddMemberToTeamCompleted

i.e the first time AddMemberToTeam is called the callback is called once, the second time AddMemberToTeam is called the callback is called twice ect.

Is there any way to remove the eventhandler from AddMemberToTeamCompleted once the eventhandler has been called or use another method which takes in the callback?


You can refer to your anonymous method from inside itself as long as you assign a delegate to a variable first:

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

_client.AddMemberToTeamCompleted += handler;

Note that you need to declare the variable and assign it separately or the compiler will deem it uninitialized when you come to use it inside the method body.


The trick to making a self-unsubscribing event-handler is to capture the handler itself so you can use it in a -=. There is a problem of declaration and definite assignment, though; so we can't do something like:

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

So instead we initialize to null first, so the declaration is before the usage, and it has a known value (null) before first used:

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


No there is no way,

Apparantly Tim and Marc have another nice solution

But you can always just name them, and do the -= on the named eventhandler on this method ;)

Guessing your event:

_client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted;

and

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

Next problem is getting this callback in your listener. Perhaps putting it on a Property in the EventArgs (but that feels kinda dirty, I agree)

0

精彩评论

暂无评论...
验证码 换一张
取 消