Subscrever e cancelar a subscrição de eventos em C#
Os eventos em C# permitem a comunicação entre objetos, permitindo que uma classe ou objeto notifique outras classes ou objetos quando algo de interesse ocorre. Esta unidade de aprendizagem centra-se nos aspetos práticos da subscrição e cancelamento de subscrição de eventos, garantindo uma utilização eficiente dos recursos e evitando armadilhas comuns como fugas de memória.
À medida que você continua desenvolvendo o aplicativo da loja de varejo, sua equipe agora está focada em garantir que as assinaturas de eventos sejam gerenciadas de forma eficaz. Por exemplo, quando um cliente conclui uma compra, você deseja que o sistema de estoque atualize os níveis de estoque e que o sistema de relatórios de vendas registre a transação. O gerenciamento adequado de assinaturas de eventos garante que esses processos sejam eficientes e não levem a vazamentos de recursos ou comportamento inesperado.
Subscrever eventos
A assinatura de um evento envolve anexar um método ao evento usando o += operador. A assinatura de eventos permite que o método seja invocado sempre que o evento for gerado.
Exemplo: Subscrever um evento
public class Button
{
public event EventHandler Clicked;
public void OnClick()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
button.Clicked += Button_Clicked;
button.OnClick(); // Output: "Button was clicked!"
}
private static void Button_Clicked(object sender, EventArgs e)
{
Console.WriteLine("Button was clicked!");
}
}
Observe que o código anterior demonstra como se inscrever em um evento usando o += operador. O Clicked evento é acionado a partir do OnClick método e o Button_Clicked método manipula o evento. A ?.Invoke sintaxe garante que o evento só seja gerado se houver assinantes.
Cancelar subscrição de eventos
Cancelar a assinatura de um evento envolve desanexar um método do evento usando o -= operador. Cancelar a assinatura de eventos é importante para evitar vazamentos de memória, especialmente quando o editor de eventos tem uma vida útil mais longa do que o assinante.
Exemplo: Cancelar a subscrição de um evento
public class Button
{
public event EventHandler Clicked;
public void OnClick()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
EventHandler handler = Button_Clicked;
button.Clicked += handler;
button.Clicked -= handler;
button.OnClick(); // No output, as the handler was unsubscribed.
}
private static void Button_Clicked(object sender, EventArgs e)
{
Console.WriteLine("Button was clicked!");
}
}
O exame desse código mostra como cancelar a assinatura de um evento usando o -= operador. Depois de cancelar a inscrição, o manipulador de eventos não é mais invocado quando o evento é gerado.
Gerir subscrições dinamicamente
Em alguns cenários, você precisa adicionar ou remover dinamicamente manipuladores de eventos com base em condições específicas. Remover manipuladores de eventos dinamicamente pode ser útil para gerenciar fluxos de trabalho complexos ou garantir que apenas manipuladores relevantes sejam anexados a qualquer momento.
Exemplo: Gestão dinâmica de subscrição
public class Button
{
public event EventHandler Clicked;
public void OnClick()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
bool isSubscribed = false;
EventHandler handler = (sender, e) => Console.WriteLine("Dynamic handler executed!");
if (!isSubscribed)
{
button.Clicked += handler;
isSubscribed = true;
}
button.OnClick(); // Output: "Dynamic handler executed!"
if (isSubscribed)
{
button.Clicked -= handler;
isSubscribed = false;
}
button.OnClick(); // No output, as the handler was unsubscribed.
}
}
Neste exemplo, o código contém assinaturas de eventos gerenciadas dinamicamente. A flag isSubscribed assegura que o manipulador seja adicionado ou removido com base em condições específicas.
Evitar fugas de memória
Podem ocorrer fugas de memória quando os manipuladores de eventos não são desinscritos, especialmente se o editor de eventos tiver uma duração maior que a do assinante. Para evitar fugas de memória, cancele sempre a subscrição de eventos quando já não forem necessários.
Práticas recomendadas para evitar vazamentos de memória:
- Use referências fracas ou
WeakEventManagerem cenários em que o tempo de vida do assinante é menor do que o do editor. - Desinscrever-se dos eventos no método
Disposede objetos descartáveis. - Evite métodos anônimos ou expressões lambda para manipuladores de eventos, a menos que você possa cancelar explicitamente a inscrição deles.
Exemplo: Cancelar inscrição em Dispose
public class Subscriber : IDisposable
{
private readonly Button _button;
public Subscriber(Button button)
{
_button = button;
_button.Clicked += Button_Clicked;
}
private void Button_Clicked(object sender, EventArgs e)
{
Console.WriteLine("Button clicked!");
}
public void Dispose()
{
_button.Clicked -= Button_Clicked;
}
}
Este exemplo de código destaca como cancelar a assinatura de eventos no Dispose método. Essa abordagem garante que os manipuladores de eventos sejam removidos corretamente, evitando vazamentos de memória quando o objeto é descartado.
Resumo
Ao entender como assinar e cancelar a assinatura de eventos, você pode garantir o uso eficiente de recursos e evitar armadilhas comuns, como vazamentos de memória. O gerenciamento adequado de eventos é essencial para a criação de aplicativos robustos e fáceis de manter.