Dispose() i zamykanie formy.

0

Debugując kod wygenerowany przez Visual Studio dla WindowsFormsApplication zauważyłem że w chwili kiedy klikam na zamknięcie formy w ( ikonke X ) to automatycznie wywoływana jest metoda:
protected override void Dispose(bool disposing) {...}. Dlaczego tak się dzieje przecież nigdzie w kodzie nie ma wywołania metody dispose() jest jedynie jej definicja. Jak to się dzieje że ona jest wywoływana ???

0

Jak to nigdzie w kodzie nie ma wywołania metody Dispose ;)? Przecież nie znasz kodu System.Windows.Forms.Form. Samo słówko override sugeruje, że definicja tej metody znajduje się również w klasie bazowej i może być przez nią wywoływana.

0

W tym kodzie nie ma jawnego wywołania metody Dispose, a mimo wszystko się wykona:

        static void Main(string[] args)
        {
            using (Form2 f2 = new Form2())
            {
                
            }
            Thread.Sleep(Int32.MaxValue);
        }
0

Metodę dispose wywołuje, chyba zdarzenie close, lub FormClosing. Tak samo naciśnięcie krzyżyka wywołuje metodę FormClosing. Dlatego nie masz w kodzie jawnego wywołania tej metody.

0
mykhaylo napisał(a)

W tym kodzie nie ma jawnego wywołania metody Dispose, a mimo wszystko się wykona:

        static void Main(string[] args)
        {
            using (Form2 f2 = new Form2())
            {
                
            }
            Thread.Sleep(Int32.MaxValue);
        }

Dobra momencik. Wiadomo, że dyrektywa using { } oznacza czas życia obiektu. Po wyjściu z zakresu using jest automatycznie wywoływane dispose(). Ale to nie jest odpowiedź na moje pytanie !!! Znalazłem już odpowiedź. Prawda jest taka,że Framework automatycznie wywołuje dispose w chwili zamknięcia danej aplikacji !!! Tak to prawda też byłem zdziwiony.

0

Ale dlaczego mamy być zdziwieni? Przecież o to chodzi, żeby przy kończeniu czegokolwiek, zwolnić zasoby. I nie tylko w przypadku zamknięcia aplikacji. Wywoływana jest ona poprzez destruktor, metodę Close, po otrzymaniu komunikatu z systemu itd.

Co może być dla ciebie bardziej szokujące, metoda Dispose w klasie Form oprócz zwolnienia elementów typowych dla formy, wywoływana jest również metoda Dispose z klasy dziedziczonej przez Form, ContainerControl. Dalej, metoda Dispose z ContainerControl wywołuje również metodę Dispose z klasy Control, z którego dziedziczy. Dalej, po zwolnieniu kolejnych rzeczy, wywoływana jest metoda Dispose z klasy Component, po którym dziedziczy Control. I dopiero tutaj wywoływane jest zdarzenie Disposed.

I możesz równie dobrze coś takiego zaimplementować we własnych klasach, to nie jest żadna magiczna właściwość Frameworka.

0

Dziwi to, że jest ona wywoływana nawet, gdy obiekt jest jeszcze potrzebny, mi często zdarzały się dziwne wyjątki NullPointerExeption gdy odwoływałem się do pól z zamkniętych już okien, mimo iż wciąż posiadałem uchwyty.
Ja też kiedyś sądziłem, że obiekt formy jest usuwany dopiero gdy nie będą istniały żadne dostępne wskaźniki na tą formę.

0

Z dokumentacji IDisposable:

private void Dispose(bool disposing)

    Dispose(bool disposing) executes in two distinct scenarios.
    If disposing equals true, the method has been called directly
    or indirectly by a user's code. Managed and unmanaged resources
    can be disposed.
    If disposing equals false, the method <b>has been called by the
    runtime from inside the finalizer</b> and you should not reference
    other objects. Only unmanaged resources can be disposed.

Tak więc jest to zachowanie celowe, udokumentowane i nie powinno dziwić :-P

Dziwi to, że jest ona wywoływana nawet, gdy obiekt jest jeszcze potrzebny, mi często zdarzały się dziwne wyjątki NullPointerExeption gdy odwoływałem się do pól z zamkniętych już okien, mimo iż wciąż posiadałem uchwyty.
Ja też kiedyś sądziłem, że obiekt formy jest usuwany dopiero gdy nie będą istniały żadne dostępne wskaźniki na tą formę.

Owszem, obiekt jest "usuwany" przez GC dopiero jak nie będą istniały żadne przyczepione referencje do niego. Wykonanie Dispose() a GC to dwie różne rzeczy.

Jeśli na obiekcie została wywołana metoda Dispose(), nie należy korzystać z referencji do niego. No ale wtedy powinien być rzucany wyjątek ObjectDisposedException.

Może po prostu gettery tych pól odwoływały się do nulla? Kto wie co dzieje się z zawartością formy po zamknięciu...

0
RUsCH napisał(a)

Ale to nie jest odpowiedź na moje pytanie !!!

Chciałem Ci pokazać kolejny przykład, gdzie nie ma jawnego wywołania metody Dispose ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1