2012-03-30 4 views
5

ich das Muster hier beschriebenen Veräußerungen verwalten: http://www.developerzen.com/2006/01/09/finalizableobject-developing-a-base-class-for-idisposable-objects/Was gilt als "nicht verwaltete Ressource" im Disposable-Muster?

Was als zählt „nicht verwaltete Ressource?“

Hier sind einige der verwirrenden Punkte in meinem Kopf sind:

  • An einem gewissen Punkt wird .NET nur Einwickeln Win32 nennt, nicht wahr? Sind also die meisten .NET-Objekte in gewisser Weise eine nicht verwaltete Ressource?
  • Was ist mit COM-Objekten, für die wir .NET-Wrapper haben - was werden sie betrachtet?
  • Was ist mit verwalteten Klassen, die Funktionalität nur von P/Invokes erhalten?
  • Was ist mit C++/CLI-Klassen, die intern native Bibliotheken verwenden? Auf der C# -Ebene implementieren die C++/CLI-Klassen, die Destruktoren hatten, jetzt IDisposable ... was werden sie betrachtet?

Ich weiß, dass Blogpost ein bisschen alt ist. Wenn es eine modernere Methode gibt, die Lebensdauer von nicht verwalteten und verwalteten Objekten zu verwalten, schlagen Sie dies bitte vor.

EDIT: Wer wählt, um dies zu schließen, geben Sie bitte einige Details, wie ich die Frage verbessern kann.

+0

* "Wenn es eine neuere Methode gibt, dieses Problem anzugehen ..." * Was genau ist das Problem hier? –

+0

Verwalten des Lebenszyklus von nicht verwalteten und verwalteten Objekten. Wenn Sie dies in der falschen Reihenfolge tun, können Sie Deadlocks haben – jglouie

+0

Was ist falsch mit dem Beispiel in [der Dokumentation] (http://msdn.microsoft.com/library/System.IDisposable.aspx)? –

Antwort

7

Ich verstehe die Verwirrung. Ich denke, es gibt ein paar einfache Richtlinien folgen:

  1. Wenn Ihre Klasse „besitzt“ einen Verweis auf ein anderes Objekt (dh das Objekt auf das andere Objekt erstellt, oder wurde den Verweis auf dieses Objekt mit dem Verständnis gegeben, dass Ihr Objekt "besitzt" es jetzt), dann sind Sie verantwortlich für alle erforderlichen Bereinigungen (falls vorhanden)

  2. Wenn dieses andere Objekt ein .NET-Objekt ist und die IDisposable-Schnittstelle nicht implementiert, dann wahrscheinlich nicht müssen alles tun. Die IDisposable-Schnittstelle ist per Konvention die Schnittstelle, mit der wir deklarieren, ob unsere Objekte aufgeräumt werden müssen.

  3. Wenn dieses andere Objekt ein .NET-Objekt ist und die IDisposable-Schnittstelle implementiert, sollte Ihre Klasse auch die IDisposable-Schnittstelle implementieren. Rufen Sie in Ihrer Dispose-Methode einfach die Dispose-Methode des anderen Objekts auf.

  4. Wenn dieses andere Objekt ein nicht verwaltetes Objekt oder eine nicht verwaltete Ressource ist, sollte Ihre Klasse einen Finalizer implementieren, um sicherzustellen, dass das nicht verwaltete Objekt/die Ressource bereinigt wird. Befolgen Sie die in diesem Blogpost beschriebenen Richtlinien, um das zu implementieren.

Im Folgenden finden Sie einige spezifische Antworten auf Ihre Fragen.

  • An einem gewissen Punkt wird Einwickeln .NET nur Win32 nennt, nicht wahr? Sind also die meisten .NET-Objekte in gewisser Weise eine nicht verwaltete Ressource?

Auch wenn ein .NET-Objekt kann einpacken Win32 nennt, der Begriff „Unmanaged Resource“ nicht geeignet ist, weil es ein .NET-Objekt ist, deshalb ist es per Definition ein „Managed Resource“. Die CLR verarbeitet die Speicherzuweisung und die Speicherbereinigung für diese Objekte.

  • Was COM-Objekte, die wir .NET-Wrapper haben für - was sie in Betracht gezogen?

.NET Wrapper-Objekte sind immer noch .NET-Objekte, so dass sie „verwalteten Ressourcen“ sind, aber beachten Sie, dass sie ihre eigenen dispose implementieren müssen/finalisieren Logik. Im Grunde kümmern sie sich darum, die "nicht verwalteten Ressourcen" zu bereinigen, damit Sie nicht müssen. Wenn Sie einen eigenen Wrapper für ein COM-Objekt implementieren, sind Sie für die Implementierung der erforderlichen Dispos/finalize-Logik verantwortlich, um sie zu bereinigen, damit die Benutzer Ihres Wrappers dies nicht tun müssen.

  • Was verwaltete Klassen, die Funktionalität ausschließlich aus P/Invokes bekommen?

Eine verwaltete Klasse, die P/Invoke verwendet nicht verwalteten Code aufrufen könnte nicht verwalteten Ressourcen werden Zuteilung, je nachdem, was es fordert.Daher kann es erforderlich sein, dass sie die erforderliche Dispos/finalize-Logik implementiert, um diese nicht verwalteten Ressourcen zu bereinigen.

  • Was ist C++/CLI-Klassen, die intern native Bibliotheken verwenden?

Ja, das auch nicht verwalteten Ressourcen werden die Zuweisung aus den nativen Bibliotheken, so ist es auch erforderlich sein, würde für sie die notwendige destructor/Finalizerthread Logik zu implementieren.

  • Am C# Ebene, die C++/CLI-Klassen, die jetzt IDisposable implementieren Destruktoren hatten ... was sie in Betracht gezogen?

In C++/CLI können Sie wählen, um eine Klasse zu deklarieren entweder (mit dem Schlüsselwort ref) verwaltete oder nicht verwaltete (ohne das Schlüsselwort ref). Wenn es mit dem Schlüsselwort ref angegeben wird, handelt es sich um eine verwaltete Klasse. Es wird auf dem verwalteten Heap zugeordnet und wird vom Garbage Collector bereinigt, sobald es nicht mehr im Gültigkeitsbereich ist und keine Referenzen mehr vorhanden sind. Wenn die Klasse ohne das Schlüsselwort ref deklariert ist, wird sie nicht verwaltet und muss explizit bereinigt werden. In beiden Fällen hat die Klasse möglicherweise nicht verwaltete Ressourcen zugewiesen, die im Destruktor/Finalizer bereinigt werden müssen.

+0

Vielen Dank für die Auseinandersetzung mit den Kugeln - das macht mir die Konzepte wirklich klar. – jglouie

0

Auf den ersten Gedanken, alles, was außerhalb .net ist unmanaged Ressource. Verwaltete Objekte sind .net Strings, Arrays, Werttypen und komplexe Typen, die aus ihnen bestehen. Alle Objekte werden verwaltet und ihr Lebenszyklus wird automatisch von .net gesteuert. String ist kein Wrapper um etwas, so dass es komplett verwaltet wird.

Die meisten .net-Basisklassen werden von Grund auf neu geschrieben, wie List, Stack usw. Wir können vereinfachen, indem wir sagen, dass jedes Objekt und seine Nachkommen nur Daten referenzieren, die in Ihrem Stack oder Heap verwaltet werden.

Alle anderen geöffneten Verbindungen/Handles, um auf Dateien außerhalb des Stacks/Heaps zuzugreifen, werden nicht verwaltet, sei es Datei, Named Pipe, Netzwerk oder irgendein anderes Gerät.

Die meisten anderen BCL-Klassen sind optimiert, aber wenn Sie sie nicht mithilfe von Block umbrechen, werden sie nicht automatisch in der Weise entsorgt, in der sie geschrieben wurden.

1

Hier ist, was ich als "unmanaged" behandeln (die Anführungszeichen beachten):

  1. Alles, was IDisposable implementiert. Wenn es entsorgt werden will ... nun, vertraue ihm. Es spielt keine Rolle, ob es sich um "sicheres" .NET handelt oder eine leere Dispose-Methode implementiert wird. Um es mit dem Disposable-Muster zu handhaben, ist es "unmanaged".
  2. Alle COM RCW. Es gibt große Debatten darüber; I view each COM->NET RCW count-increase as "owned" and thus "unmanaged". Letztendlich ein RCW wird sich im Destruktor aufräumen, aber "letztlich" kann viele Probleme verursachen, wenn es um das Outlook-Objektmodell geht, mit dem ich arbeite. Dieser Ansatz erfordert einen konsistenten Ansatz für den Umgang mit COM-Objekten und Lebensdauern, um "RCW-getrennte" Probleme zu vermeiden.
  3. Beliebige [neue] Ressource erhalten durch einen P/Invoke-Aufruf wie einem BSTR: die Sache, die die Ressource zuweist "besitzt" es, bis die Kontrolle aufgegeben wird. Dies ist wirklich eine "unmanaged" Ressource und muss freigegeben werden. Es gibt einige hilfreiche Wrapper-Typen für die verschiedenen Ressourcen, die zugewiesen werden können.

Ich beschäftige mich nicht mit Nicht-COM nativen Code (z CLI), ein paar WinAPI Anrufe ausgenommen, die alle C.

Verwandte Themen