2010-06-21 15 views
19

मेरे पास कक्षा DocumentGenerator है जो MemoryStream को लपेटती है। तो मैंने कक्षा में IDisposable लागू किया है।एएसपी.नेट में फ़ाइल डाउनलोड को लागू करते समय मैं अपने फाइलस्ट्रीम का निपटान कैसे करूं?

मैं नहीं देख सकता कि मैं इसे कहां/कहाँ संभवतः निपट सकता हूं।

यह मेरे वर्तमान कोड है, जो MVC में एक फ़ाइल डाउनलोड करता है:

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

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

इस त्रुटि के रूप में धारा निपटाए से पहले नियंत्रक इसके साथ समाप्त हो गया है बंद कर दिया है /। मैं कैसे सुनिश्चित कर सकता हूं कि इस स्थिति में मेरे संसाधनों का उचित तरीके से निपटान किया जा सके?

संपादित करें: इस समय IDisposable का मेरा कार्यान्वयन बस MemoryStream का निपटान करता है। मुझे पता है कि यह उचित कार्यान्वयन नहीं है, मैंने अभी इसे एक परीक्षण के रूप में इस्तेमाल किया है। क्या यह काम करने के लिए मैं कुछ अलग कर सकता हूं?

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

क्या आप हमें IDISposable के कार्यान्वयन को दिखा सकते हैं? – DHN

+0

क्या '_ms' वही है जो आपको 'GetDocumentStream' पर कॉल करने के बाद मिलता है? –

+0

@ Jordão: हाँ यह सही है, इसलिए समस्या है। – fearofawhackplanet

उत्तर

29

आपको स्ट्रीम को निपटाने की आवश्यकता नहीं है। इसे FileStreamResult.WriteFile विधि द्वारा निपटाया जाएगा। इस कक्षा से कोड अंश:

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

using पर ध्यान दें। जब आप अपने नियंत्रक से File(dg.GetDocumentStream(), "text/plain", filename) पर कॉल करते हैं तो यह उस कन्स्ट्रक्टर को आमंत्रित करता है जो स्ट्रीम को सार्वजनिक संपत्ति में संग्रहीत करता है जिसे प्रतिपादन के दौरान निपटाया जाता है।

निष्कर्ष: आपको dg.GetDocumentStream() के साथ स्ट्रीम प्राप्त करने के बारे में चिंता करने की आवश्यकता नहीं है।

+1

क्या आपकी स्ट्रीम किसी अन्य डिस्पोजेबल ऑब्जेक्ट से आती है जैसे HttpWebResponse? क्या मुझे HttpWebResponse का निपटान करने की चिंता करनी चाहिए या बस यह मान लें कि उसे कचरा इकट्ठा किया जाएगा? उदाहरण 'var प्रतिक्रिया = (HttpWebResponse) request.GetResponse(); वापसी फ़ाइल (प्रतिक्रिया.GetResponseStream(), "छवि/जेपीईजी"); ' –

0

बस क्या Darin has said, यह इस अवधारणा को ध्यान देना महत्वपूर्ण है में जोड़ने के लिए:

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

आप इसे कैसे अपने विधि में प्रयोग कर रहे हैं के बावजूद, ब्लॉक का उपयोग सुनिश्चित करता है कि निपटान हमेशा कहा जाता है, यह महत्वपूर्ण है जब है आप रिटर्न कथन के रूप में उपयोग ब्लॉक के परिणाम का उपयोग करने पर विचार करते हैं, यह इसे निपटाने से नहीं रोकेगा ....

संबंधित मुद्दे

 संबंधित मुद्दे