Ich habe den folgenden Code
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Die dispose()
Methode wird am Ende von using
Anweisungsklammern aufgerufen, }
oder? Wird das Objekt ordnungsgemäß entsorgt, da ich return
vor dem Ende der using
Anweisung bin MemoryStream
? was geschieht hier?
Antworten:
Ja,
Dispose
wird angerufen. Es wird aufgerufen, sobald die Ausführung den Bereich desusing
Blocks verlässt , unabhängig davon, welche Mittel zum Verlassen des Blocks erforderlich waren, sei es das Ende der Ausführung des Blocks, einereturn
Anweisung oder eine Ausnahme.Wie @Noldorin richtig hervorhebt, wird die Verwendung eines
using
Blocks im Code intry
/ kompiliertfinally
,Dispose
wobei imfinally
Block aufgerufen wird . Zum Beispiel der folgende Code:effektiv wird:
Da
finally
die Ausführung garantiert ist, nachdem dertry
Block die Ausführung beendet hat, wird unabhängig von seinem AusführungspfadDispose
garantiert, dass er aufgerufen wird, egal was passiert.Weitere Informationen finden Sie in diesem MSDN-Artikel .
Nachtrag:
Nur eine kleine Einschränkung: Da
Dispose
der Aufruf garantiert ist, ist es fast immer eine gute Idee, sicherzustellen, dassDispose
bei der Implementierung niemals eine Ausnahme ausgelöst wirdIDisposable
. Leider gibt es einige Klassen in der Kernbibliothek, die unter bestimmten Umständen auslösen, wenn sieDispose
aufgerufen werden - ich sehe Sie an, WCF-Dienstreferenz / Client-Proxy! - und wenn dies passiert, kann es sehr schwierig sein, die ursprüngliche Ausnahme aufzuspüren, wennDispose
sie während eines Abwickelns des Ausnahmestapels aufgerufen wurde, da die ursprüngliche Ausnahme zugunsten der neuen Ausnahme verschluckt wird, die durch denDispose
Aufruf generiert wird . Es kann unglaublich frustrierend sein. Oder ist das frustrierend verrückt? Einer der Beiden. Vielleicht beide.quelle
Dispose
in finally kompiliert wurde , sodass die Implementierung von effektiv funktioniertfinally
, wie Sie beschreiben.using
Anweisungen verhalten sich genau wietry ... finally
Blöcke und werden daher immer auf Code-Exit-Pfaden ausgeführt. Ich glaube jedoch, dass sie den sehr wenigen und seltenen Situationen unterliegen, in denenfinally
Blöcke nicht aufgerufen werden. Ein Beispiel, an das ich mich erinnern kann, ist, wenn der Vordergrund-Thread beendet wird, während Hintergrund-Threads aktiv sind: Alle Threads außer dem GC werden angehalten, was bedeutetfinally
, dass keine Blöcke ausgeführt werden.Offensichtliche Bearbeitung: Abgesehen von der Logik, mit der sie mit IDisposable-Objekten umgehen können, verhalten sie sich gleich, d'oh.
Bonusinhalt: Sie können gestapelt werden (wobei sich die Typen unterscheiden):
Und auch durch Kommas getrennt (wo die Typen gleich sind):
quelle
Ihr MemoryStream-Objekt wird ordnungsgemäß entsorgt, Sie müssen sich darüber keine Sorgen machen.
quelle
Mit der
using
Anweisung wird das Objekt unabhängig vom Abschlusspfad entsorgt.Weiterführende Literatur ...
quelle
Sehen Sie sich Ihren Code im Reflektor an, nachdem Sie ihn kompiliert haben. Sie werden feststellen, dass der Compiler den Code umgestaltet, um sicherzustellen, dass dispose im Stream aufgerufen wird.
quelle