65 votes

Ne Stream.Disposer toujours d'appel de Flux.De près (et de Flux.Flush)

Si j'ai la situation suivante:

StreamWriter MySW = null;
try
{
   Stream MyStream = new FileStream("asdf.txt");
   MySW = new StreamWriter(MyStream);
   MySW.Write("blah");
}
finally
{
   if (MySW != null)
   {
      MySW.Flush();
      MySW.Close();
      MySW.Dispose();
   }
}

Puis-je juste appelez - MySW.Dispose() et de sauter la clôture, même si c'est prévu? Il n'existe aucun Flux implimentations qui ne fonctionnent pas comme prévu (Comme CryptoStream)?

Si non, alors est la suivante tout simplement mauvais code:

using (StreamWriter MySW = new StreamWriter(MyStream))
{
   MySW.Write("Blah");
}

83voto

Binary Worrier Points 27424

Je peux juste appeler MySW.Dispose() et sauter la clôture, même si elle est fourni?

Oui c'est ce que c'est.

Il n'existe aucun Flux implimentations qui ne fonctionnent pas comme prévu (Comme CryptoStream)?

Il est sûr de supposer que si un objet implémente IDispose, qu'il va disposer de lui-même correctement.

Si elle n'est pas le cas, alors ce serait un bug.

Si non, alors est la suivante tout simplement mauvais code:

Non, ce code est la meilleure façon de traiter avec des objets qui implémentent IDispose.

. . . plus d'excellentes informations dans la accepté de répondre à cette question de Près et Jetez - qui appeler?

59voto

Andrew Hare Points 159332

J'ai utilisé un Réflecteur et a constaté que System.IO.Stream.Dispose ressemble à ceci:

public void Dispose()
{
    this.Close();
}

22voto

ScottS Points 5247

Comme Daniel Bruckner mentionné, de Céder et de Proximité sont effectivement la même chose.

Cependant Flux n'est PAS d'appeler la méthode Flush() lorsqu'il est disposé/fermé. FileStream (et je suppose que n'importe quel Flux avec un mécanisme de mise en cache) ne appeler la méthode Flush() lors de son élimination.

Si vous êtes l'extension de Flux, ou MemoryStream etc. vous devrez mettre en place un appel à la méthode Flush() en cas de cession/fermé si c'est nécessaire.

3voto

Tamas Czinege Points 49277

Les Deux StreamWriter.Dispose() et de Flux.Dispose() libérer toutes les ressources détenues par les objets. Deux d'entre eux de fermer le flux sous-jacent.

Le code source du cours d'eau.Dispose() (à noter que c'est la mise en œuvre de détails, alors ne comptez pas sur elle):

public void Dispose()
{
    this.Close();
}

StreamWriter.Dispose() (comme avec Stream.Dispose()):

protected override void Dispose(bool disposing)
{
    try
    {
        // Not relevant things
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            try
            {
                if (disposing)
                {
                    this.stream.Close();
                }
            }
            finally
            {
                // Not relevant things
            }
        }
    }
}

Pourtant, j'ai l'habitude implicitement à proximité des ruisseaux/streamwriters avant de les jeter - je pense que c'est plus propre.

3voto

clemahieu Points 1237

Pour les objets qui doivent être manuellement fermé, tous les efforts devraient être faits pour créer l'objet en utilisant le bloc.

//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
   //Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream'

De cette façon, on ne peut jamais tort d'accès "stream", hors du contexte de l'utilisation de la clause et le fichier est toujours fermé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X