Удаление анонимного обработчика событий - PullRequest
26 голосов
/ 29 ноября 2010

У меня есть следующий код, где 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, он добавляет еще один обратный вызов к клиенту. AddMemberToTeamCompleted

т.е. первый раз, когда AddMemberToTeam вызывается, обратный вызов вызывается один раз, второй раз, когда AddMemberToTeam вызывается, обратный вызов вызывается дважды и т. д.

Есть ли способ удалить обработчик событий из AddMemberToTeamCompleted после вызова или использования обработчика событийдругой метод, который принимает в обратном вызове?

Ответы [ 3 ]

53 голосов
/ 29 ноября 2010

Вы можете ссылаться на свой анонимный метод изнутри самого себя, если вы сначала назначаете делегата переменной:

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

_client.AddMemberToTeamCompleted += handler;

Обратите внимание, что вам нужно объявить переменную и назначить ее отдельно, иначе компилятор сочтет ее неинициализированной, когда вы начнете использовать ее внутри тела метода.

18 голосов
/ 29 ноября 2010

Хитрость в создании отписавшегося обработчика событий состоит в том, чтобы перехватить сам обработчик , чтобы вы могли использовать его в -=. Однако существует проблема объявления и определенного назначения ; поэтому мы не можем сделать что-то вроде:

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 голосов
/ 29 ноября 2010

Нет, нет,

Очевидно, у Тима и Марка есть еще одно приятное решение

Но вы всегда можете просто назвать их и сделать -= в именованном обработчике событий для этого метода;)

угадал ваше событие:

_client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted;

и

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

Следующая проблема заключается в получении этого обратного вызова в вашем слушателе. Возможно, поместив его в свойство в EventArgs (но это выглядит немного грязно, я согласен)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...