Welches rufe ich an?
Ist es notwendig, beide anzurufen?
Wird der andere eine Ausnahme auslösen, wenn ich bereits einen von ihnen angerufen habe?
c#
.net
garbage-collection
Ashwnacharya
quelle
quelle
Antworten:
Close()
undDispose()
wenn man dazu aufgefordert wirdMemoryStream
, dient man nur dazu, zwei Dinge zu tun:MemoryStream
Es stehen keine nicht verwalteten Ressourcen zur Verfügung, sodass Sie diese technisch nicht entsorgen müssen. Der Effekt, a nicht zu entsorgen,MemoryStream
ist ungefähr der gleiche wie das Löschen eines Verweises auf abyte[]
- der GC bereinigt beide auf die gleiche Weise.Die
Dispose()
Methode der Streams wird direkt an dieClose()
Methode 2 delegiert , sodass beide genau dasselbe tun.In der Dokumentation wird
IDisposable.Dispose()
ausdrücklich angegeben, dass es sicher istDispose()
, jedes Objekt 3 mehrmals aufzurufen . (Wenn dies für eine bestimmte Klasse nicht zutrifft, implementiert diese Klasse dieIDisposable
Schnittstelle auf eine Weise, die gegen ihren Vertrag verstößt, und dies wäre ein Fehler.)Das alles zu sagen: Es macht wirklich keinen großen Unterschied, ob Sie einen entsorgen
MemoryStream
oder nicht. Der einzige wirkliche Grund, warum esClose
/Dispose
Methoden hat, ist, dass es von erbtStream
, was erfordert, dass diese Methoden als Teil seines Vertrags Streams unterstützen, die nicht verwaltete Ressourcen haben (wie Datei- oder Socket-Deskriptoren).1 Die Implementierung von Mono gibt die
byte[]
Referenz nicht frei . Ich weiß nicht, ob die Microsoft-Implementierung dies tut.2 "Diese Methode ruft Close auf, das dann Stream.Dispose (Boolean) aufruft."
3 "Wenn die Dispose-Methode eines Objekts mehrmals aufgerufen wird, muss das Objekt alle Aufrufe nach dem ersten ignorieren."
quelle
MemoryStream
, der die Arbeit des GC erleichtert, nur gilt, wenn Sie aus irgendeinem Grund einen Verweis auf das entsorgte Stream-Objekt hatten.1
gibt laut .NET-Referenzquelle.Dispose()
auch die internebyte[]
nicht frei. Die einzige Ressource, die festgelegtnull
wird_lastReadTask
, wird nur in der Methode verwendetTask<int> ReadAsync(byte[], int, int, CancellationToken)
. Neben Einstellung , dass eine Variable null alle ist es gesetzt_isOpen
,_writable
und_expandable
zufalse
.Nichts des oben Genannten. Sie müssen weder anrufen
Close
nochDispose
.MemoryStream
enthält keine nicht verwalteten Ressourcen, daher ist die einzige Ressource, die zurückgefordert werden kann, Speicher. Der Speicher wird während der Speicherbereinigung mit dem Rest desMemoryStream
Objekts zurückgefordert, wenn Ihr Code nicht mehr auf das verweistMemoryStream
.Wenn Sie einen langlebigen Verweis auf das haben
MemoryStream
, können Sie diesen Verweis auf null setzen, damit derMemoryStream
Müll gesammelt werden kann.Close
undDispose
befreien Sie weder den Dampfpuffer noch dasMemoryStream
eigentliche Objekt.Da weder ein Finalizer
Stream
nochMemoryStream
ein Finalizer vorhanden sind, müssen Sie nicht aufrufenClose
oder aufrufen lassenDispose
,GC.SuppressFinalize
um die Speicherbereinigung zu optimieren. Es gibt keinen zu unterdrückenden Finalizer.In den Dokumenten für MemoryStream heißt es:
quelle
Sie können den
using
Block dafür verwenden. Es wird automatisch aufgerufen,Dispose
wenn es außerhalb seines Bereichs liegt.Beispiel:
using (MemoryStream ms = new MemoryStream()) { // Do something with ms.. } // ms is disposed here
Hoffe das hat geholfen.
quelle
Verwenden Sie
using
block, damit Ihr Objekt entsorgt wird, wenn es dieIDisposable
Schnittstelle implementiertquelle
Jeder von ihnen.
Nein, beides ist ausreichend.
Nein, das Einwegmuster erklärt, dass nachfolgende Aufrufe von Dispose keine negativen Auswirkungen haben.
quelle
Der folgende Code ist Stream.Dispose vom Reflektor, wie Sie sehen können, müssen Sie nicht schließen, wenn Sie entsorgen (was bei Verwendung von implizit ist)
public void Dispose() { this.Close(); }
quelle
Wenn Sie Close () aufrufen, wird Dispose () intern aufgerufen, um die Ressourcen freizugeben.
Weitere Informationen finden Sie unter diesem Link: msdn
quelle
Nur anrufen reicht aus
Dispose()
=)quelle
In .NET 3.5 (andere Versionen wurden nicht überprüft) werden Methoden beim Entsorgen eines MemoryStream in der folgenden Reihenfolge aufgerufen:
quelle
Als erste Lösung wird empfohlen, wo immer möglich Anweisungen zu verwenden. Dies wird hier beschrieben: http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Wenn wir jetzt zu der Frage kommen, wie andere in den meisten .NET Framework-Klassen vorgeschlagen haben, gibt es keinen Unterschied zwischen Close () und Dispose (), und es spielt keine Rolle, welche der beiden Methoden Sie aufrufen. Sie sollten einen anrufen, aber nicht beide. Es gibt jedoch Ausnahmen .
Ausführliche Informationen finden Sie hier: https://blogs.msdn.microsoft.com/kimhamil/2008/03/15/the-often-non-difference-between-close-and-dispose/
quelle