Removendo o manipulador de events anônimos

Eu tenho o seguinte código onde SprintServiceClient é uma referência a um WCF Service-

public class OnlineService { private SprintServiceClient _client; public OnlineService() { _client = new SprintServiceClient(); } public void AddMemberToTeam(MemberModel user, int projectId, Action callback) { _client.AddMemberToTeamCompleted += (s, e) => callback(e.Result); _client.AddMemberToTeamAsync(user.ToUser(), projectId); } } 

O problema é que toda vez que AddMemberToTeam é chamado, ele adiciona outro callback ao client.AddMemberToTeamCompleted

ou seja, a primeira vez que AddMemberToTeam é chamado o retorno de chamada é chamado uma vez, a segunda vez AddMemberToTeam é chamado o retorno de chamada é chamado duas vezes ect.

Existe alguma maneira de remover o manipulador de events de AddMemberToTeamCompleted uma vez que o manipulador de events tenha sido chamado ou use outro método que leva no retorno de chamada?

Você pode se referir ao seu método anônimo dentro de si, desde que atribua um delegado a uma variável primeiro:

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

Note que você precisa declarar a variável e atribuí-la separadamente ou o compilador a considerará não inicializada quando você vier a usá-la dentro do corpo do método.

O truque para fazer um manipulador de events de auto-desinscrição é capturar o próprio manipulador para que você possa usá-lo em um -= . Há um problema de declaração e designação definida ; então não podemos fazer algo como:

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

Então, em vez disso, inicializamos para null primeiro, portanto, a declaração é anterior ao uso e tem um valor conhecido ( null ) antes de ser usado pela primeira vez:

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

Não tem jeito,

Aparentemente Tim e Marc têm outra boa solução

Mas você pode sempre nomeá-los e fazer o -= no manipulador de events nomeado neste método;)

Adivinhando seu evento:

 _client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted; 

e

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

O próximo problema é obter esse retorno de chamada no ouvinte. Talvez colocando em uma propriedade no EventArgs (mas isso é meio sujo, eu concordo)