Wie kann ich wissen, ob eine Klasse in C# unmanaged ist
das dich auf dem falschen Weg bekommt sofort, alle Klassen in C# verwaltet werden. Die Sprache unterstützt überhaupt keine nicht verwalteten Klassen. Keine der .NET-Sprachen, außer einem: C++/CLI. Dies ist eine eher untypische Sprache, die speziell dafür entwickelt wurde, einem Programmierer die Verwendung einer nativen C++ - Klasse zu erleichtern. Die Verwendung dieser Sprache ist spezialisiert und für diese Frage nicht relevant.
Es kommt darauf an, ob die verwaltete Klasse ein Wrapper für eine nicht verwaltete Ressource ist. Ein Wrapper ist die Art von Klasse, die über eine rein verwaltete Schnittstelle verfügt, aber intern eine nicht verwaltete Ressource verwendet, normalerweise über pinvoke mit dem Attribut [DllImport]. Die Ressource wird fast immer mit einem IntPtr
dargestellt. Ein nicht verwalteter Griff oder Zeiger.
Ein solcher Wrapper benötigt einen Finalizer, um sicherzustellen, dass die nicht verwaltete Ressource immer freigegeben wird. Wenn das nicht passiert, dann haben Sie eine Leck, die Art von Fehler, der (schließlich) ein Programm abstürzt, wenn das Betriebssystem über ein Programm verärgert wird, das zu viele Ressourcen verwendet.
Und da es einen Finalizer hat, implementiert es auch IDisposable. Ermöglichen, dass ein Programm die nicht verwaltete Ressource vorzeitig freigibt, bevor der GC den Finalizer aufruft. Die Verwendung der Dispose() - Methode oder unter Verwendung der-Anweisung ist optional. Der Finalizer ist gut genug, um sicherzustellen, dass der Job ausgeführt wird.
Aber manchmal ist der Finalizer nicht gut genug, weil ein Programm nicht schnell genug Müll erzeugt und dann ist es ziemlich wichtig, dass Sie helfen. Sie können nicht wirklich wissen, ob Sie helfen müssen, also tun die meisten .NET-Programmierer immer. Und eine Untergruppe hat nie ein Problem in Jahren der Programmierung bemerkt und nie bemerkt. Wir hören schließlich von ihnen SO an :)
Ihr Beispiel eines Stream ist gut, um zum nächsten Schritt zu gelangen. StreamReader umschließt eine nicht verwaltete Ressource nicht. Der gesamte Code ist in C# geschrieben und es hat keinen Pin-Voke, es gibt keinen unmanaged Bone in seinem Körper. Und deshalb nicht haben einen Finalizer. Hat aber immer noch eine Dispose() -Methode.
StreamReader wurde "infiziert".Es ist auch eine Wrapper-Klasse, aber für einen Stream, kein IntPtr. Ein rein verwalteter abstrakter .NET-Typ, der selbst ein Wrapper ist. Welche implementiert IDisposable, jetzt StreamReader hat, um es auch zu implementieren. Wenn Sie also die Dispose() - Methode des StreamReaders aufrufen, kann die Stream.Dispose() -Methode ausgeführt werden.
Dies ist Layering bei der Arbeit gibt es eine Hierarchie von Klassen. StreamReader umschließt den Stream, der FileStream umhüllt, der SafeFileHandle umhüllt, wobei eigentlich den IntPtr umschließt. Nur SafeFileHandle hat einen Finalizer.
Das Verstehen der Schichten ist der Ort, an dem jeder aufgibt, der ziemlich genaue Einblicke in die Struktur dieser .NET-Klassen erfordert. Sie können dorthin gelangen, aber es dauert Jahre. Es gibt drei grundlegende Verknüpfungen:
Haben Sie ein Verständnis, wie ein Betriebssystem funktioniert. Gibt Ihnen den Einblick, dass eine Datei eine Betriebssystemressource ist, wetten Sie darauf, dass wenn Sie eine Datei verwenden, sie entsorgt oder geschlossen werden muss.
Verwenden Sie den MSDN Library-Artikel für die Klasse, die Sie verwenden. Wenn Sie sehen, dass es eine Dispose() -Methode hat, gibt es fast immer einen guten Grund, sie zu verwenden. Manchmal gibt es nicht, aber Sie werden nie falsch liegen, wenn Sie es trotzdem benutzen.
In Schwierigkeiten geraten, machen Sie alle Fehler, die jeder Programmierer machen muss, verwenden Sie SO oder einen Speicherprofiler, um herauszufinden, was Sie falsch gemacht haben. Nichts ist falsch daran zu lernen, wie man es richtig macht.
Einfach: Sie können nicht. – ckruczek
Also, was ist die beste Praxis, um in Fällen zu handeln? Besonders von Ihnen verwenden Bibliotheken von Drittanbietern? – Fabian
Alles, was IDisposable implementiert, sollte entfernt werden, wenn Sie damit fertig sind. – erikH