2010-06-21 24 views
19

Tôi có một lớp DocumentGenerator kết thúc tốt đẹp một MemoryStream. Vì vậy, tôi đã thực hiện IDisposable trên lớp học.Làm cách nào để xử lý luồng phim của tôi khi triển khai tải xuống tệp trong ASP.NET?

Tôi không thể thấy cách/nơi tôi có thể bỏ qua.

Đây là mã hiện tại của tôi, mà thực hiện một download tập tin trong MVC:

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

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

này lỗi như con suối bị đóng/thanh lý khoản trước khi bộ điều khiển đã hoàn thành với nó. Làm cách nào để đảm bảo tài nguyên của tôi được xử lý đúng cách trong tình huống này?

CHỈNH SỬA: Thực hiện của tôi IDisposable tại thời điểm này chỉ phân phát MemoryStream. Tôi biết nó không phải là một thực hiện đúng, tôi chỉ sử dụng nó như là một thử nghiệm. Có điều gì khác mà tôi có thể làm ở đây để làm cho nó hoạt động không?

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

Bạn có thể chỉ cho chúng tôi việc triển khai IDisposable được không? – DHN

+0

Đó có phải là '_ms' giống như bạn nhận được sau khi gọi' GetDocumentStream' không? –

+0

@ Jordão: đúng vậy, do đó vấn đề. – fearofawhackplanet

Trả lời

29

Bạn không cần phải vứt bỏ luồng. Nó sẽ được xử lý theo phương pháp FileStreamResult.WriteFile. Trích đoạn mã từ lớp này:

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

Lưu ý using. Khi bạn gọi File(dg.GetDocumentStream(), "text/plain", filename) từ bộ điều khiển của bạn, điều này sẽ gọi hàm tạo lưu trữ luồng vào một thuộc tính công khai được xử lý trong khi hiển thị.

Kết luận: bạn không cần phải lo lắng về việc xử lý luồng có được với dg.GetDocumentStream().

+1

Điều gì sẽ xảy ra nếu luồng của bạn đến từ một đối tượng dùng một lần khác như HttpWebResponse? Tôi có nên lo lắng về việc xử lý HttpWebResponse hay chỉ giả định rằng nó sẽ bị thu gom rác? Ví dụ 'var response = (HttpWebResponse) request.GetResponse(); tệp trả về (response.GetResponseStream(), "image/JPEG"); ' –

0

Chỉ cần thêm những gì Darin has said, điều quan trọng cần lưu ý khái niệm này:

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

Bất kể thế nào bạn đang sử dụng nó trong phương pháp của bạn, khối sử dụng đảm bảo rằng Vứt bỏ luôn gọi, điều này rất quan trọng khi bạn xem xét sử dụng kết quả của khối sử dụng như một câu lệnh trả về, nó sẽ không ngăn nó bị xử lý ....

Các vấn đề liên quan