2010-06-21 4 views
19

Tengo una clase DocumentGenerator que envuelve MemoryStream. Así que he implementado IDisposable en la clase.¿Cómo elimino mi filestream al implementar una descarga de archivos en ASP.NET?

No veo cómo/dónde puedo desecharlo.

Este es mi código actual, que realiza una descarga de archivos en MVC:

using (DocumentGenerator dg = DocumentGenerator.OpenTemplate(path)) 
{ 
    /* some document manipulation with the 
     DocumentGenerator goes here ...*/ 

    return File(dg.GetDocumentStream(), "text/plain", filename); 
} 

Este errores como la corriente está cerrado/dispuestos antes que el controlador ha terminado con él. ¿Cómo puedo asegurarme de que mis recursos se eliminen adecuadamente en esta situación?

EDIT: Mi implementación de IDisposable por el momento solo dispone de MemoryStream. Sé que no es una implementación adecuada, solo la utilicé como prueba. ¿Hay algo diferente que pueda hacer aquí para que funcione?

public void Dispose() 
{ 
    _ms.Dispose(); 
    _ms = null; 
} 
+1

¿Puede mostrarnos la implementación de IDisposable, por favor? – DHN

+0

¿Es eso '_ms' lo mismo que recibes después de llamar a' GetDocumentStream'? –

+0

@ Jordão: sí, eso es correcto, de ahí el problema. – fearofawhackplanet

Respuesta

29

No necesita disponer de la transmisión. Se eliminará mediante el método FileStreamResult.WriteFile. extracto de código de esta clase:

public FileStreamResult(Stream fileStream, string contentType) : base(contentType) 
{ 
    if (fileStream == null) 
    { 
     throw new ArgumentNullException("fileStream"); 
    } 
    this.FileStream = fileStream; 
} 

protected override void WriteFile(HttpResponseBase response) 
{ 
    Stream outputStream = response.OutputStream; 
    using (this.FileStream) 
    { 
     byte[] buffer = new byte[0x1000]; 
     while (true) 
     { 
      int count = this.FileStream.Read(buffer, 0, 0x1000); 
      if (count == 0) 
      { 
       return; 
      } 
      outputStream.Write(buffer, 0, count); 
     } 
    } 
} 

Aviso del using. Cuando llama al File(dg.GetDocumentStream(), "text/plain", filename) desde su controlador, esto invoca el constructor que almacena la secuencia en una propiedad pública que se desecha durante la representación.

Conclusión: no necesita preocuparse por la eliminación de la corriente obtener con dg.GetDocumentStream().

+1

¿Qué pasa si su flujo proviene de otro objeto desechable como HttpWebResponse? ¿Debo preocuparme por tirar la HttpWebResponse o simplemente asumir que se recogerá la basura? Ejemplo 'var response = (HttpWebResponse) request.GetResponse(); return File (response.GetResponseStream(), "image/JPEG"); ' –

0

sólo para añadir a lo Darin has said, es importante tener en cuenta este concepto:

public Stream GetDownloadFile(...) 
{ 
    using (var stream = new MemoryStream()) { 
    return stream; 
    } 
} 

public Stream GetDownloadFile(...) 
{ 
    using (var generator = DocumentGenerator.OpenTemplate(path)) 
    { 
    // Document manipulation. 

    return File(generator.GetDocumentStream(), "text/plain", filename); 
    } 
} 

Independientemente de cómo se está utilizando en su método, el bloque usando asegura que Desechar siempre se llama, esto es importante cuando Considera utilizar el resultado del bloque de uso como declaración de retorno, no evitará que se elimine ...

Cuestiones relacionadas