2010-06-21 6 views
19

Ich habe eine Klasse DocumentGenerator, die eine MemoryStream umschließt. Also habe ich IDisposable auf die Klasse implementiert.Wie kann ich meinen Filestream bei der Implementierung eines Dateidownloads in ASP.NET entfernen?

Ich kann nicht sehen, wie/wo ich es möglicherweise entsorgen kann.

Dies ist meine aktuellen Code, der eine Datei herunterladen in MVC führt:

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

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

Dieser Fehler als der Strom/angeordnet geschlossen ist, bevor die Steuerung mit ihm fertig ist. Wie kann ich sicherstellen, dass meine Ressourcen in dieser Situation ordnungsgemäß entsorgt werden?

EDIT: Meine Implementierung von IDisposable im Moment verfügt nur über die MemoryStream. Ich weiß, dass es keine richtige Implementierung ist, ich habe es nur als Test verwendet. Kann ich hier etwas anderes machen, damit es funktioniert?

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

Können Sie uns bitte die Implementierung von IDisposable zeigen? – DHN

+0

Ist das _mss dasselbe, das Sie nach dem Aufruf von GetDocumentStream erhalten? –

+0

@ Jordão: Ja, das ist richtig, daher das Problem. – fearofawhackplanet

Antwort

29

Sie müssen den Stream nicht entsorgen. Es wird durch die FileStreamResult.WriteFile Methode entsorgt. Code-Auszug aus dieser Klasse:

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

Beachten Sie die using. Wenn Sie File(dg.GetDocumentStream(), "text/plain", filename) von Ihrem Controller aufrufen, ruft dies den Konstruktor auf, der den Stream in einer öffentlichen Eigenschaft speichert, die während des Renderings entsorgt wird.

Fazit: Sie müssen sich keine Sorgen über die Entsorgung des Stromes mit dg.GetDocumentStream().

+1

Was ist, wenn Ihr Stream von einem anderen verfügbaren Objekt wie HttpWebResponse kommt? Sollte ich mir darüber sorgen, die HttpWebResponse zu entsorgen oder einfach davon ausgehen, dass Müll gesammelt wird? Beispiel 'var response = (HttpWebResponse) request.GetResponse(); Rückgabedatei (response.GetResponseStream(), "image/JPEG"); ' –

0

Nur um hinzuzufügen, was Darin has said, ist es wichtig, dieses Konzept zu beachten:

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

Unabhängig davon, wie Sie es in Ihrer Methode verwenden, ist die Verwendung von Block stellt sicher, dass Entsorgen immer genannt wird, ist dies wichtig, wenn Sie erwägen, das Ergebnis des using-Blocks als Rückgabeanweisung zu verwenden, es wird nicht daran gehindert, entsorgt zu werden.