Domanda

Se ho la seguente situazione:

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();
   }
}

Posso chiamare MySW.Dispose() e saltare il primo, anche se è previsto? Ci sono implimentations Ruscello che non funzionano come previsto (come CryptoStream)?

In caso contrario, è il seguente codice solo male:

using (StreamWriter MySW = new StreamWriter(MyStream))
{
   MySW.Write("Blah");
}
È stato utile?

Soluzione

  

Posso chiamare MySW.Dispose () e   saltare il primo anche se è   a condizione?

Sì, questo è quello che è per.

  

Ci sono implementazioni Ruscello   che non funzionano come previsto (come   CryptoStream)?

È lecito ritenere che se un oggetto implementa IDisposable, esso cederà stessa correttamente.

Se non lo fa, allora sarebbe un bug.

  

In caso contrario, è la seguente solo male   codice:

No, che il codice è il metodo consigliato di trattare con gli oggetti che implementano IDisposable.

Per informazioni più eccellente è nella risposta accettato di Chiudere e Dispose - che chiamare?

Altri suggerimenti

Ho usato Reflector e ha scoperto che System.IO.Stream.Dispose assomiglia a questo:

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

Come detto Daniel Bruckner, di disporne e chiudere sono di fatto la stessa cosa.

Tuttavia stream non chiama filo () quando è disposto / chiuso. FileStream (e presumo qualsiasi altro flusso con un meccanismo di cache) fa chiamata filo () quando disposto.

Se si estende Stream o MemoryStream ecc dovrai implementare una chiamata a flush () quando disposto / chiuso se è necessario.

Sia StreamWriter.Dispose () e Stream.Dispose () rilasciare tutte le risorse possedute dagli oggetti. Entrambi chiudere il flusso sottostante.

Il codice sorgente di Stream.Dispose () (notare che questo è i dettagli di implementazione in modo da non si basano su di esso):

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

StreamWriter.Dispose () (stesso con 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
            }
        }
    }
}

Ancora, io di solito implicitamente torrenti stretti / streamwriters prima di smaltimento - penso che sembra più pulito

.

Tutti i flussi standard (FileStream, CryptoStream) cercheranno di irrigare quando chiuso / disposta. Penso che si possa fare affidamento su questo per eventuali implementazioni flusso di Microsoft.

Come risultato, chiudere / smaltimento può generare un'eccezione se il colore non riesce.

In realtà IIRC c'era un bug nell'implementazione .NET 1.0 di FileStream in quanto non riuscirebbe a liberare l'handle di file se il filo genera un'eccezione. Questo è stato risolto in .NET 1.1 con l'aggiunta di un blocco try / finally al metodo Dispose (Boolean).

Per gli oggetti che devono essere chiusi manualmente, ogni sforzo dovrebbe essere fatto per creare l'oggetto in un blocco utilizzando.

//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' 

In questo modo non si può mai accedere in modo non corretto 'flusso' fuori dal contesto della clausola di utilizzo e il file è sempre chiuso.

Ho guardato nel codice .NET per la classe Stream, aveva il seguente che suggerirebbe che sì è possibile ...

    // Stream used to require that all cleanup logic went into Close(),
    // which was thought up before we invented IDisposable.  However, we 
    // need to follow the IDisposable pattern so that users can write
    // sensible subclasses without needing to inspect all their base
    // classes, and without worrying about version brittleness, from a
    // base class switching to the Dispose pattern.  We're moving 
    // Stream to the Dispose(bool) pattern - that's where all subclasses
    // should put their cleanup starting in V2. 
    public virtual void Close() 
    {
        Dispose(true); 
        GC.SuppressFinalize(this);
    }

    public void Dispose() 
    {
        Close(); 
    } 

Stream.Close è implementato da una chiamata a Stream.Dispose o viceversa - così i metodi sono equivalenti. Stream.Close esiste solo perché la chiusura di un flusso di suoni più naturale di smaltire un flusso.

Inoltre si dovrebbe cercare di evitare le chiamate esplicite a questo metodi e utilizzare l'istruzione using invece al fine di ottenere corretta gestione delle eccezioni gratuitamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top