Mam zamiar utworzyć GUI, który będzie dynamicznie tworzył zestawy kontrolek z przypisanymi im zdarzeniami. Będę musiał dodać i usunąć te kontrolki w czasie wykonywania. Będzie to wyglądać tak:Środki ostrożności, które należy podjąć, aby zapobiec wyciekom pamięci z powodu dodanych uchwytów zdarzeń.
FlowLayoutPanel.Controls.Clear();
<< add new controls, assigning Click events with += >>
Słyszałem, że przypisywanie obsługi zdarzeń z + = może spowodować wycieki pamięci (więcej specificly, pamięć nie zostanie zwolniona dopóki aplikacja nie zakończy działania). Chcę tego uniknąć. Wiem, że mogę napisać kilka funkcji, takich jak tutaj How to remove all event handlers from a control, aby znaleźć wszystkie programy do obsługi zdarzeń i je usunąć, ale wygląda to bardzo skomplikowanie.
Czy istnieje inny sposób? Czy wywołanie Dispose help usuwa te procedury obsługi zdarzeń? Czy potrafisz niszczyć obiekty, aby wymusić ich pamięć, tak jak w C/C++?
Dzięki!
PS: Problem polega na tym, że nie wiem, co wydarzenie się rozłączy. Stworzę wiele etykiet i dodaję do nich różne rodzaje zdarzeń onclick. Kiedy nadszedł czas czyszczenia panelu układu przepływu, nie ma możliwości sprawdzenia, który program obsługi zdarzenia został dołączony do której etykiety.
To jest przykładowy kod (_flowLP to FlowLayoutPanel) - ta funkcja Refresh() jest uruchamiana wiele razy przed zakończeniem aplikacji.
private void Refresh()
{
Label l;
Random rnd = new Random();
// What code should i add here to prevent memory leaks
_flowLP.Controls.Clear();
l = new Label();
l.Text = "1";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "2";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "3";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "4";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "5";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "6";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
}
Odnośnie do edycji: Jeśli metod dodanych do listy wywołań zdarzenia nie można na pewno określić, można zachować delegatów, które zostały dodane do obsługi zdarzeń w zbiorze gdzieś i użyć go do usunięcia delegatów, gdy czas pochodzi. Lub, jeśli wiesz, że całkowicie usuwasz listy inwokacji zdarzeń, po prostu usuń je całkowicie. – phoog