Gibt es eine Methode oder eine andere leichte Methode, um zu überprüfen, ob sich eine Referenz auf ein entsorgtes Objekt bezieht?
PS - Dies ist nur eine Kuriosität (gut schlafen, nicht im Produktionscode). Ja, ich weiß, dass ich das ObjectDisposedException
beim Versuch, auf ein Mitglied des Objekts zuzugreifen, abfangen kann .
c#
.net
dispose
idisposable
Neil C. Obremski
quelle
quelle
bool IsDisposed { get; }
Erklärung dazu gibtSystem.IDisposable
.Dispose
Methode weist ein Objekt an, alle Ressourcen freizugeben, die es erworben, aber noch nicht freigegeben hat. Wenn ein Objekt niemals Ressourcen enthält, muss seineDispose
Methode im Allgemeinen nichts tun. Wenn der Typ deklariertvoid IDisposable.Dispose() {};
, kann er andernfallsIDisposable
ohne Overhead pro Instanz ignorieren . EineIsDisposed
Eigenschaft, von der erwartet wurde, dass sie nach einemDispose
Aufruf wahr wird , würde das Hinzufügen eines ansonsten unnötigen Booleschen Flags zu jeder Instanz vieler Typen erfordern, die sonst ignoriert werden könntenDispose
.IDisposable
, wie können Sie überprüfen, ob es zuerst entsorgt wurde? Anstatt davon auszugehen, dass dies nicht der Fall ist, und eine Ausnahme zu erwischen? Oder sollen Sie das Leben so gestalten, dass Sie immer wissen, ob es entsorgt ist oder nicht?IsDisposed
Flag kann dazu beitragen, zu verhindern, dass Code Zeit für Vorgänge verschwendet, die möglicherweise nicht erfolgreich sind. In dem Fall, in dem ein Objekt zwischen derIsDisposed
Prüfung und dem Versuch, es zu verwenden, entsorgt wird, müssen jedoch noch Ausnahmen behandelt werden .WeakReference
scheint hier relevant. Es ist nicht gerade ein IDipose-Detektor, aber es sagt Ihnen, ob es GC-Detektor istAntworten:
Nein - Die Standardimplementierung des IDisposable-Musters unterstützt dies nicht
quelle
System.Windows.Forms.Control
hat eineIsDisposed
Eigenschaft, die nach demDispose()
Aufruf auf true gesetzt ist . In Ihren eigenen IDisposable-Objekten können Sie problemlos eine ähnliche Eigenschaft erstellen.quelle
Es ist nichts eingebaut, was dies zulässt. Sie müssten eine boolesche IsDisposed-Eigenschaft verfügbar machen, die ein internes disposed-Flag widerspiegelt.
quelle
IDisposablePlus
oder was auch immer) zu definieren , die vonIDisposable
und enthältbool IsDisposed { get; }
. Auf diese Weise können Sie leicht erkennen, welche IhrerIDisposable
Objekte unterstützt werdenIsDisposed
.Wenn es nicht Ihre Klasse ist und keine IsDisposed-Eigenschaft (oder etwas Ähnliches - der Name ist nur eine Konvention) bereitstellt, haben Sie keine Möglichkeit zu wissen.
Wenn es sich jedoch um Ihre Klasse handelt und Sie der kanonischen IDisposable-Implementierung folgen , legen Sie einfach das Feld _disposed oder _isDisposed als Eigenschaft offen und überprüfen Sie dies.
quelle
Die
Dispose
Methode ist erforderlich, um alle erforderlichen Bereinigungen durchzuführen, bevor ein Objekt verlassen wird. Wenn keine Bereinigung erforderlich ist, muss nichts unternommen werden. Wenn ein Objekt nachverfolgen muss, ob es entsorgt wurde, selbst wenn dieDispose
Methode sonst nichts tun würde, müssten vieleIDisposable
Objekte ein Flag hinzufügen, um einen sehr begrenzten Nutzen zu erzielen.Es wäre möglicherweise hilfreich gewesen, wenn
IDisposable
zwei Eigenschaften enthalten wären - eine, die angibt, ob ein Objekt entsorgt werden muss , und eine, die angibt, dass das Objekt durch Entsorgung nicht unbrauchbar gemacht wurde. Bei Objekten, bei denen die Entsorgung tatsächlich etwas bewirkt, sind beide Werte zunächst wahr und werden danach falschDispose
. Bei Objekten, bei denen für die Entsorgung keine Bereinigung erforderlich ist, kann die erste Methode immer false und die zweite immer true zurückgeben, ohne dass irgendwo ein Flag gespeichert werden muss. Ich glaube jedoch nicht, dass diese jetzt zu .NET hinzugefügt werden können.quelle
IDisposable
es keineDisposed
Eigenschaft gibt, ist, dass es als seltsam empfunden worden wäre, Objekte zu haben, bei denen der AufrufDispose
eine solche Eigenschaft nicht festlegen würdetrue
, aber dass Objekte nachverfolgen müssen, obDispose
sie in Fällen aufgerufen wurden, in denen Sie hätten sonst keinen Grund zur Sorge, würden erhebliche Kosten und wenig Nutzen verursachen.Ich sehe, dass dies alt ist, aber ich habe keine Antwort gesehen. Einige nicht alle verfügbaren Objekte wie ein DataSet verfügen über ein entsorgtes Ereignis, das Sie anhängen können.
quelle
Disposed
event ein Mitglied derSystem.ComponentModel.IComponent
Schnittstelle.Ich deklariere die Objekte gerne, ohne sie zu initialisieren, aber setze ihre Standardwerte auf
Nothing
. Dann schreibe ich am Ende der Schleife:Hier ist ein vollständiges Beispiel:
Dies funktioniert auch hervorragend, um Ihre Hauptobjekte an die Spitze einer Routine zu setzen, sie in einer
Try
Routine zu verwenden und sie dann in einemFinally
Block zu entsorgen :quelle
Using
Anweisung zu verwenden? Das gab es sicherlich schon 2013, als diese Antwort geschrieben wurde.inputPdf
Ihre Antwort einmal auf einen anderen Wert (als Nichts) gesetzt wurde, kann Ihre Antwort nicht erkennen, obinputPdf
sie entsorgt wurde. Sie können dies teilweise beheben, indem Sie esinputPdf = Nothing
nach der Entsorgung einstellen . Dies würde jedoch keinen anderen Variablen helfen , die auf dasselbe Objekt wie gezeigt wurdeninputPdf
. Das heißt , wenn Sie tun:inputPdf = New PdfReader
,Dim pdf2 As PdfReader = inputPdf
,inputPdf.Dispose
,inputPdf = Nothing
, gibt es noch keine Möglichkeit wäre , zu wissen , dasspdf2
angeordnet ist (es ist das gleiche Objekt wieinputPdf
).