Подтвердить что ты не робот

Удаление анонимного обработчика событий

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

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

4b9b3361

Ответ 1

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

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

_client.AddMemberToTeamCompleted += handler;

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

Ответ 2

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

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;

Ответ 3

Нет никакого способа,

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

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

Угадайте свое событие:

_client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted;

и

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

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