Tome a seguinte classe C #:
c1 {
event EventHandler someEvent;
}
Se houver muitas inscrições para c1
o someEvent
evento e eu quiser limpá-las, qual é a melhor maneira de conseguir isso? Considere também que as assinaturas deste evento podem ser / são delegadas lambdas / anônimas.
Atualmente, minha solução é adicionar um ResetSubscriptions()
método c1
que define someEvent
como nulo. Não sei se isso tem consequências invisíveis.
EventHandlerList
, você poderá. Você teria que reconhecer esses dois casos - e poderia haver várias outras implementações.hidden
.Adicione um método a c1 que definirá 'someEvent' como nulo.
fonte
É melhor usar
delegate { }
donull
que evitar a exceção de ref nula.fonte
List.Clear()
vsmyList = null
.Definir o evento como nulo dentro da classe funciona. Quando você descarta uma classe, sempre deve definir o evento como nulo, o GC tem problemas com os eventos e pode não limpar a classe descartada se houver eventos pendentes.
fonte
A melhor prática para limpar todos os assinantes é definir o someEvent como null, adicionando outro método público, se você quiser expor essa funcionalidade para fora. Isso não tem consequências invisíveis. A pré-condição é lembrar de declarar SomeEvent com a palavra-chave 'event'.
Por favor, veja o livro - C # 4.0 em poucas palavras, página 125.
Alguém aqui propôs usar o
Delegate.RemoveAll
método. Se você o usar, o código de exemplo pode seguir o formulário abaixo. Mas é realmente estúpido. Por que não apenasSomeEvent=null
dentro daClearSubscribers()
função?fonte
Você pode conseguir isso usando os métodos Delegate.Remove ou Delegate.RemoveAll.
fonte
Comentário chato estendido conceitual.
Prefiro usar a palavra "manipulador de eventos" em vez de "evento" ou "delegar". E usou a palavra "evento" para outras coisas. Em algumas linguagens de programação (VB.NET, Object Pascal, Objective-C), "event" é chamado de "message" ou "signal" e até possui uma palavra-chave "message" e sintaxe específica do sugar.
E, para responder a essa "mensagem", um "manipulador de eventos" responde, seja um único delegado ou vários delegados.
Resumo: "Evento" é a "pergunta", "manipulador (es) de evento" são a resposta (s).
fonte
Esta é a minha solução:
É necessário chamar
Dispose()
ou usar ousing(new Foo()){/*...*/}
padrão para cancelar a assinatura de todos os membros da lista de chamadas .fonte
Remova todos os eventos, suponha que o evento seja do tipo "Ação":
fonte
GetInvocationList
.Em vez de adicionar e remover retornos de chamada manualmente e declarar vários tipos de delegados em todos os lugares:
Você pode tentar esta abordagem genérica:
fonte