Padrões de eventos e armadilhas (vazamentos de memória)
Identifique e corrija armadilhas de eventos: cancele a assinatura para evitar vazamentos de memória, armazene referências aos delegados para removê-los e use um padrão de assinatura IDisposable.
Padrões de eventos e armadilhas (vazamentos de memória) é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 3 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 3 aulas no total.
Visão geral das armadilhas
Objetivo: usar eventos com segurança.
- Cancele a assinatura para evitar vazamentos de memória
- Mantenha uma referência ao mesmo manipulador para removê-lo
- Prefira um pequeno padrão de IDisposable para a limpeza
- Evite manipuladores anônimos embutidos que não possam ser desconectados
Cancele a assinatura para evitar vazamentos
Os eventos mantêm referências aos assinantes. Se o publicador tiver vida longa e você nunca o desconectar, o assinante não poderá ser coletado.
using System;
public class Publisher
{
public event EventHandler Tick;
public void Fire()
{
EventHandler h = Tick;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Subscriber
{
public void Handle(object s, EventArgs e)
{
Console.WriteLine("Handling tick");
}
public void Subscribe(Publisher p) { p.Tick += Handle; }
public void Unsubscribe(Publisher p) { p.Tick -= Handle; } // required to avoid leaks
}
public class Program
{
public static void Main(string[] args)
{
Publisher p = new Publisher();
Subscriber s = new Subscriber();
s.Subscribe(p);
p.Fire(); // prints once
s.Unsubscribe(p); // detach when done
s = null; // now eligible for GC in a real app
p.Fire(); // no output
}
}
Mantenha a referência do manipulador
Para desconectar um manipulador anônimo, armazene-o em uma variável e passe a mesma instância para -=.
using System;
public class Button
{
public event EventHandler Click;
public void Simulate()
{
EventHandler h = Click;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Button b = new Button();
// BAD: cannot easily remove this later
// b.Click += (s, e) => Console.WriteLine("inline");
// GOOD: store the handler, attach, later detach the same instance
EventHandler saved = (s, e) => Console.WriteLine("saved");
b.Click += saved;
b.Simulate(); // prints "saved"
b.Click -= saved; // can remove because we kept the reference
b.Simulate(); // no output
}
}
Assinatura descartável
Retorne um IDisposable de Subscribe. Use using para cancelar a assinatura automaticamente.
using System;
public class Ticker
{
public event EventHandler Tick;
public IDisposable Subscribe(EventHandler handler)
{
Tick += handler;
return new Unsubscriber(this, handler);
}
private sealed class Unsubscriber : IDisposable
{
private Ticker _t;
private EventHandler _h;
private bool _done;
public Unsubscriber(Ticker t, EventHandler h) { _t = t; _h = h; }
public void Dispose()
{
if (!_done)
{
_t.Tick -= _h;
_done = true;
}
}
}
public void Fire()
{
EventHandler h = Tick;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Ticker t = new Ticker();
using (t.Subscribe((s, e) => Console.WriteLine("tick")))
{
t.Fire(); // prints once
}
t.Fire(); // nothing after disposal
}
}
Desconexão com try/finally
Use try/finally quando um manipulador precisar ser desconectado mesmo que uma exceção seja lançada.
using System;
public class Alarm
{
public event EventHandler Ring;
public void Trigger()
{
EventHandler h = Ring;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Alarm a = new Alarm();
EventHandler h = (s, e) => Console.WriteLine("ring");
a.Ring += h;
try
{
a.Trigger(); // do work with subscription active
}
finally
{
a.Ring -= h; // always detach
}
a.Trigger(); // no output
}
}
Dicas para evitar vazamentos
Dicas:
- Os assinantes devem gerenciar o próprio cancelamento de assinatura (Dispose, finally ou um método explícito).
- Evite assinar usando manipuladores anônimos embutidos que não possam ser removidos.
- Tenha cuidado com eventos estáticos; eles geralmente sobrevivem aos objetos.
- Mantenha os manipuladores curtos; não bloqueie o publicador.
Causa de vazamentos com eventos
Recapitulação
Recapitulação: cancele a assinatura para evitar vazamentos, armazene referências aos manipuladores para removê-los e prefira padrões de limpeza descartáveis ou baseados em finally para garantir tempos de vida seguros dos eventos.
Perguntas Frequentes
A aula “Padrões de eventos e armadilhas (vazamentos de memória)” é grátis?
Sim — o texto completo de “Padrões de eventos e armadilhas (vazamentos de memória)” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 3 aulas no total.
O que vou aprender em “Padrões de eventos e armadilhas (vazamentos de memória)”?
Identifique e corrija armadilhas de eventos: cancele a assinatura para evitar vazamentos de memória, armazene referências aos delegados para removê-los e use um padrão de assinatura IDisposable. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 3.
Quanto tempo leva a aula “Padrões de eventos e armadilhas (vazamentos de memória)”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- delegate, Action/Func, fechamentos
- Eventos: publicação/assinatura, palavra-chave event
- Padrões de eventos e armadilhas (vazamentos de memória)