Disposing von Unmanaged Resourcen

Disposing von Unmanaged Resourcen

Beitragvon Razer » 01.08.2012 20:50

Hallo Leute,

sehe ich das richtig, dass wenn meine Klasse VertexBuffer, welcher einen nativen Buffer wrappt und einige Funktionen hinzufügt,
IDisposable implementiert und dort den nativen Buffer freigibt, dass es reicht wenn ich im Destruktor Dispose() aufrufe, damit ich sicher gehen kann,
dass das Ding automatisch sobald es verworfen wurde, auch korrekt freigegeben wird?

Sprich, wenn ich eine neue Instant auf das selbe Objekt lege, so sollte der GC normal die alte Instanz, welche nicht mehr referenziert wird, einsammeln und Finalize aufrufen.
Im Grunde wäre das ja dann der Destruktor-Aufruf und somit automatisch ein Dispose-Vorgang für unmanaged Resourcen, oder?


Ich bin mir nämlich grade sehr unsicher ob ich das Prinzip nicht missverstanden habe und mein Programm durch die Buffer und Co. auf einmal lauter Memory Leaks erzeugt...

Danke euch ;)
R
Benutzeravatar
Razer
 
Beiträge: 514
Registriert: 24.02.2012 20:08
Wohnort: Nahe Deutschland (Bayern)

Re: Disposing von Unmanaged Resourcen

Beitragvon Glatzemann » 01.08.2012 21:24

Dispose in den Destruktor zu packen ist nicht unüblich und durchaus eine gute Idee. Du musst aber in die Dispose-Methode entsprechende Prüfungen reinbringen -> Mehrfacher Aufruf von Dispose darf unter keinen Umständen zu Problemen irgendeiner Art führen, daß ist sogar eine offizielle Microsoft-Konvention.

Sowas muss also möglich sein, ohne das es Exceptions gibt:

Code: Alles auswählen

using (MyInheritedVertexBuffer vb = new MyInheritedVertexBuffer) // using ruft automatisch Dispose auf, wenn die Klammer verlassen wird
{
  vb.Dispose();
  vb = null;
}


Bei diesem Code wird theoretisch bis zu dreimal Dispose aufgerufen. Zweimal aber auf jeden Fall, der dritte Fall tritt nur dann ein, wenn nach "vb = null" der Garbage-Collector loslaufen sollte, bevor die Using-Klammer abgeschlossen ist.
Benutzeravatar
Glatzemann
Administrator
 
Beiträge: 2079
Registriert: 08.02.2012 13:35
Wohnort: Leverkusen

Re: Disposing von Unmanaged Resourcen

Beitragvon Razer » 01.08.2012 22:06

Ah ok, gut zu wissen. Denn genau das wär wohl das nächste mal am Kopf kratzen gewesen, wenn auf einmal die Exceptions fliegen.
Hab das per "disposed"-Flag gelöst. Bei mehrfachem Aufruf passiert also nichts.

Danke dir ;)

MfG
R
Benutzeravatar
Razer
 
Beiträge: 514
Registriert: 24.02.2012 20:08
Wohnort: Nahe Deutschland (Bayern)

Re: Disposing von Unmanaged Resourcen

Beitragvon Glatzemann » 01.08.2012 22:24

Gerne :-)

Ich verzichte meist auf das Dispose-Flag und mache in Dispose ungefähr sowas:

Code: Alles auswählen
public void Dispose()
{
  if (myUnmanagedResource != null)
  {
    myUnmanagedResource.CleanupAndDestroy();  // der Aufräumcode halt
    myUnmanagedResource = null;
  }
}


Im Grunde das gleiche wie es auch in C++ wäre (direkt aus meinem Dungeon-Projekt an einer Stelle, wo ich mal keinen shared_ptr verwende, der das automatisch macht):

Code: Alles auswählen
   if (m_rasterState)
   {
      m_rasterState->Release();
      m_rasterState = NULL;
   }
Benutzeravatar
Glatzemann
Administrator
 
Beiträge: 2079
Registriert: 08.02.2012 13:35
Wohnort: Leverkusen

Re: Disposing von Unmanaged Resourcen

Beitragvon Razer » 01.08.2012 23:08

Stimmt, kommt natürlich drauf an, wie viele unmanaged Resourcen man hat.
Irgendwann ist es doch etwas umständlich für jede Resource eine Abfrage zu machen, anstatt Flags zu nutzen ;)
Benutzeravatar
Razer
 
Beiträge: 514
Registriert: 24.02.2012 20:08
Wohnort: Nahe Deutschland (Bayern)

Re: Disposing von Unmanaged Resourcen

Beitragvon Glatzemann » 02.08.2012 05:46

Klar, wenn du 20 (oder auch 5) unmanaged Resourcen in einer Klasse kapselst, dann ist das ein bisschen mehr Arbeit als ein einzelnes Flag. Aber in diesem Fall liegt fast immer ein schlechtes Design vor.
Benutzeravatar
Glatzemann
Administrator
 
Beiträge: 2079
Registriert: 08.02.2012 13:35
Wohnort: Leverkusen


Zurück zu C#

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast