Welches rufe ich an?
Müssen Sie beide anrufen?
Wird der andere eine Ausnahme auslösen, wenn ich bereits einen von ihnen angerufen habe?
Close()
und Dispose()
dienen bei Aufruf einer MemoryStream
nur zu zwei Zwecken:
MemoryStream
verfügt über keine nicht verwalteten Ressourcen, die Sie nicht zur Verfügung haben müssen, so dass Sie technisch nicht darüber verfügen müssen. Das Fehlen einer MemoryStream
hat in etwa die gleiche Wirkung, als wenn Sie einen Verweis auf einen byte[]
löschen - der GC wird beide auf dieselbe Weise bereinigen.
Welches rufe ich an? Müssen Sie beide anrufen?
Die Dispose()
-Methode von Streams direkt an die Close()
-Methode delegieren2, also machen beide genau dasselbe.
Wird der andere eine Ausnahme auslösen, wenn ich bereits einen von ihnen angerufen habe?
Die Dokumentation für IDisposable.Dispose()
besagt ausdrücklich, dass es sicher ist, Dispose()
für jedes Objekt mehrmals aufzurufen3. (Wenn dies für eine bestimmte Klasse nicht zutrifft, implementiert diese Klasse die IDisposable
-Schnittstelle in einer Weise, die ihren Vertrag verletzt, und dies wäre ein Fehler.)
All dies zu sagen: Es macht wirklich keinen großen Unterschied, ob Sie eine MemoryStream
haben oder nicht. Der einzige wirkliche Grund, warum es Close
Dispose
-Methoden gibt, ist, dass sie von Stream
erbt. Dies erfordert, dass diese Methoden als Teil ihres Vertrages Streams unterstützen, die _/do über nicht verwaltete Ressourcen (wie Datei- oder Socket-Deskriptoren) verfügen.
1 Monos Implementierung gibt die byte[]
-Referenz nicht frei. Ich weiß nicht, ob die Microsoft-Implementierung dies tut.
2 "Diese Methode ruft Close auf und ruft dann Stream.Dispose (Boolean) auf."
3 "Wenn die Dispose-Methode eines Objekts mehrmals aufgerufen wird, muss das Objekt alle Aufrufe nach dem ersten ignorieren."
Verwenden Sie den using
-Block, damit Ihr Objekt verworfen wird, wenn dessen IDisposable
-Schnittstelle implementiert ist
Sie können dazu den using
-Block verwenden. Es ruft automatisch Dispose
auf, wenn es seinen Bereich verlässt.
Beispiel:
using (MemoryStream ms = new MemoryStream())
{
// Do something with ms..
}
// ms is disposed here
Hoffe das hat geholfen.
der folgende Code ist Stream.Dispose aus Reflektor. Wie Sie sehen können, müssen Sie nicht schließen, wenn Sie die Daten löschen.
public void Dispose()
{
this.Close();
}
Welches rufe ich an?
Jeder von ihnen.
Müssen Sie beide anrufen?
Nein, beides ist ausreichend.
Wird der andere eine Ausnahme auslösen, wenn ich bereits einen von ihnen angerufen habe?
Nein, das Einwegmuster gibt an, dass nachfolgende Aufrufe von Dispose keine negativen Auswirkungen haben.
Beim Aufruf von Close () wird intern Dispose () aufgerufen, um die Ressourcen freizugeben.
Siehe diesen Link für weitere Informationen: msdn
Aufruf nur Dispose()
macht den Trick =)
In .NET 3.5 (andere Versionen nicht geprüft) werden Methoden beim Disponieren eines MemoryStream in der folgenden Reihenfolge aufgerufen:
Als erste Lösung wird empfohlen, möglichst Anweisungen zu verwenden. Dies wird hier beschrieben: http://msdn.Microsoft.com/en-us/library/yh598w02.aspx
Wenn die Lebensdauer eines IDisposable-Objekts auf eine einzelne Methode beschränkt ist, sollten Sie es in der using-Anweisung deklarieren und instanziieren. Die using-Anweisung ruft die Dispose-Methode für das Objekt auf die richtige Art und Weise auf, und (wenn Sie sie wie oben gezeigt verwenden), bewirkt auch das Objekt selbst, sobald der Dispose-Aufruf aufgerufen wird. Within Im Verwendungsblock ist das Objekt schreibgeschützt und kann nicht geändert oder neu zugewiesen werden.
Kommen wir jetzt zu der Frage: Wie in den meisten .NET-Framework-Klassen vorgeschlagen, gibt es keinen Unterschied zwischen Close () und Dispose (), und es ist egal, welche der beiden Methoden Sie aufrufen. Sie sollten eine anrufen, aber nicht beide. Es gibt Ausnahmen.
Es gibt Ausnahmen; Zum Beispiel verhalten sich System.Windows.Forms.Form und System.Data.SqlClient.SqlConnection bei Close () und Dispose () unterschiedlich.
Für vollständige Details können Sie hier nachschauen: https://blogs.msdn.Microsoft.com/kimhamil/2008/03/15/the-often-non-difference-zwischenclose-und-dispose/
Nichts des oben Genannten. Sie müssen weder Close
noch Dispose
aufrufen.
MemoryStream
enthält keine nicht verwalteten Ressourcen. Die einzige Ressource, die zurückgefordert werden soll, ist der Arbeitsspeicher. Der Speicher wird während der Speicherbereinigung mit dem Rest des Objekts MemoryStream
zurückgefordert, wenn der Code nicht mehr auf die Variable MemoryStream
verweist.
Wenn Sie einen langlebigen Verweis auf die Variable MemoryStream
haben, können Sie diesen Verweis auf null setzen, um zu ermöglichen, dass die Variable MemoryStream
Garbage gesammelt wird. Close
und Dispose
geben weder den eigentlichen Steam-Puffer noch das MemoryStream
-Objekt frei.
Da weder Stream
noch MemoryStream
über einen Finalizer verfügen, müssen Sie Close
oder Dispose
nicht aufrufen, damit GC.SuppressFinalize
aufgerufen wird, um die Garbage Collection zu optimieren. Es gibt keinen Finalizer zum Unterdrücken.
Die Dokumente für MemoryStream setzen es so:
Dieser Typ implementiert die
IDisposable
-Schnittstelle, verfügt jedoch nicht über tatsächlich verfügbare Ressourcen. Das bedeutet, dass die Entsorgung durch direktes Aufrufen vonDispose()
oder durch Verwendung eines Sprachkonstrukts wieusing
(in C #) oderUsing
(in Visual Basic) nicht erforderlich ist.