Laden...

Dispatchertimer "Dispose" - sichergehen, dass er gelöscht wird

Erstellt von EyeTrackJack vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.347 Views
E
EyeTrackJack Themenstarter:in
35 Beiträge seit 2019
vor 4 Jahren
Dispatchertimer "Dispose" - sichergehen, dass er gelöscht wird

Hallo,
Ich habe eine Klasse (MouseMover), die einen Dispatchertimer (MouseMoveTimer) enthält und nicht immer verwendet wird bzw. während der Laufzeit gelöscht werden muss.
An welcher Stelle in der Klasse muss veranlasst werden, dass der Timer gelöscht wird? Ich habe bis jetzt Folgendes. Ist es so korrekt? Und vor allem, muss das so kompliziert sein? Es geht doch nur darum, den Timer am Ende loszuwerden, wenn die Klasse nicht mehr benötigt wird.

       
        public MouseMover()
        {
            MouseMoveTimer.Tick += MouseMoveTimer_Tick; //der besagte Dispatchertimer
        }

        ~MouseMover()
        {
            Dispose(false);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Code to dispose the managed resources of the class
            }

            // Code to dispose the un-managed resources of the class
            MouseMoveTimer.Stop();
            MouseMoveTimer.Tick -= MouseMoveTimer_Tick;
            MouseMoveTimer = null;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
T
2.219 Beiträge seit 2008
vor 4 Jahren

Soweit ich dies auf den ersten Blick sehen kann, ist DispatcherTimer eine normale Klase die nicht disposed werden muss.
Entsprechend kann der GC deine Klasse dann auch ohne Dispose/Finalizer wegräumen.

Links:
DispatcherTimer Doku
Referenz Code von DispatcherTimer

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

E
EyeTrackJack Themenstarter:in
35 Beiträge seit 2019
vor 4 Jahren

Das Problem ist, dass der Timer gestoppt werden muss, bevor die Klasse aus dem Speicher entfernt wird. Er läuft sonst weiter und ich habe keine Kontrolle darüber mehr.

T
2.219 Beiträge seit 2008
vor 4 Jahren

Dann reicht ein einfacher Aufruf in Disposed, was du ja bereits hast.
Ggf. noch mit einer isDisposed Member Variable prüfen ob Dispose schon durchgelaufen ist.
Wenn ja, musst du ja nichts mehr machen.

Nachtrag:
Du brauchst dann auch keine MouseMoveTimer nicht auf null setzen.
Wenn dein Objekt vom GC weggeräumt wird, kümmert er sich darum.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

301 Beiträge seit 2009
vor 4 Jahren

bevor die Klasse aus dem Speicher entfernt wird. Er läuft sonst weiter und ich habe keine Kontrolle darüber mehr.

Ist das wirklich so? Ich bin mir da nicht so sicher. mMn. hat diese Dispose Implementierung gar keinen Vorteil

16.806 Beiträge seit 2008
vor 4 Jahren

Timer jerglicher Art kann man super einfacher und sicherer - und viel besser - mit Rx umsetzen.
Reactive Extensions (Rx) – Part 4 – Replacing Timers

Du brauchst dann auch keine MouseMoveTimer nicht auf null setzen.
T-Virus

Es gilt zum guten Ton (und irgendwo gibt es auch eine Empfehlung dazu), dass das Objekt auf null gesetzt werden soll.
Nach dem Disposen ist das Objekt in seiner ursprünglichen Form ohnehin nicht mehr nutzbar.

Der Vorteil beim Null: kann das Objekt null sein, sagen Dir statische Codechecks an den gewissen Stellen, dass man vor einem Zugriff auf null checken sollte, solltest Du extern irgendwo drauf zugreifen.
Darauf kann man deutlich besser und stabiler reagieren als auf eine Disposed-Exception.

T
2.219 Beiträge seit 2008
vor 4 Jahren

@Abt
Wäre mir ehrlich gesagt neu.
Ich kenne es nur bei Handles, dass man diese auch auf IntPtr.Zero setzten sollte.
Auch in der Doku finde sich kein Beispiel oder Hinweis dazu, dass man hier explizit Null setzen sollte.
Wäre es nicht sogar im Sinne des Dispose Musters, wenn die interna dann auch eine Dispose Meldung liefern anstelle von null?
Null ist für mich eher ein Indikator einer fehlenden Initalisierung, nicht aber einer Freigabe durch ein Dispose.

Nachtrag:
Ein schnelles Beispiel wäre z.B. in SqlConnection.
Dort wird im Dispose dann die Credentials und das Access Token genullt.
In diesem Szenario macht es auch Sinn, damit diese Daten nicht mehr im Speicher hängen obwhl die Verbindung terminiert ist.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 4 Jahren

Wäre es nicht sogar im Sinne des Dispose Musters, wenn die interna dann auch eine Dispose Meldung liefern anstelle von null?

Nicht wirklich. Externer Code muss die Implementierung von Dispose nicht kennen.

Null ist für mich eher ein Indikator einer fehlenden Initalisierung, nicht aber einer Freigabe durch ein Dispose.

Naja, das ist ja nicht der Sinn von null.

In diesem Szenario macht es auch Sinn, damit diese Daten nicht mehr im Speicher hängen obwhl die Verbindung terminiert ist.

Mit dem Satz widersprichst Du Dir abstrakt selbst.
"nicht mehr im Speicher hängen" trifft ja auf eine gewisse Art und Weise auf jede Dispose-Implementierung zu. 😉