Ho intenzione di dare l'opinione dissenziente. La risposta alla domanda specifica "È necessario avvolgere StreamWriter in un blocco usando?" è in realtà No. In effetti, si non deve chiamare Dispose su StreamWriter, perché Dispose è progettato male e fa la cosa sbagliata.
Il problema con StreamWriter è che, quando lo si elimina, disattiva il flusso sottostante. Se hai creato StreamWriter con un nome file e ha creato internamente il proprio FileStream, questo comportamento sarebbe del tutto appropriato. Ma se, come qui, hai creato StreamWriter con uno stream esistente, allora questo comportamento è assolutamente The Wrong Thing (tm). Ma lo fa comunque.
codice come questo non funzionerà:
var stream = new MemoryStream();
using (var writer = new StreamWriter(stream)) { ... }
stream.Position = 0;
using (var reader = new StreamReader(stream)) { ... }
perché quando using
blocco del StreamWriter dispone la StreamWriter, che a sua volta buttare via la corrente. Quindi quando provi a leggere dallo stream, ottieni una ObjectDisposedException.
StreamWriter è un'orribile violazione della regola "ripulisci il tuo casino". Cerca di ripulire il caos di qualcun altro, che lo volessero o meno.
(immaginate se si è tentato questo nella vita reale. Prova spiegare alla polizia perché si è rotto nella casa di qualcun altro e cominciò a gettare tutte le loro cose nel cestino ...)
Per questo motivo, ho considera StreamWriter (e StreamReader, che fa la stessa cosa) tra le poche classi in cui "se implementa IDisposable, dovresti chiamare Dispose" è sbagliato. Mai chiamata Dispose su StreamWriter che è stato creato su uno stream esistente. Chiama Flush() invece.
Quindi assicurati di ripulire il flusso quando necessario. (Come Joe ha sottolineato, ASP.NET dispone la Response.OutputStream per voi, quindi non c'è bisogno di preoccuparsi qui.)
Attenzione: se non gettare lo StreamWriter, allora si fai devi chiamare Flush() quando hai finito di scrivere. In caso contrario, è possibile che i dati vengano ancora memorizzati in memoria in memoria e che non giungano mai al flusso di output.
La mia regola per StreamReader è, fingere di non implementare IDisposable. Lascia perdere quando hai finito.
La mia regola per StreamWriter è, chiama Flush dove altrimenti avresti chiamato Dispose. (Questo significa che dovete usare un try
.. finally
invece di un using
.)
Se il programma si chiude, le maniglie avranno ripulito. L'istruzione using aiuta solo mentre l'app è in esecuzione. –
Finalizzatori sono il termine per ciò che fa la pulizia all'uscita. – Guvante