2010-10-20 15 views
28

"ऑब्जेक्ट एक बार से अधिक का निपटारा किया जा सकता है" जब मैं कोड की निम्न हिस्सा पर कोड विश्लेषण चलाने मैं यह संदेश प्राप्त:त्रुटि

वस्तु 'धारा' विधि में एक बार से अधिक निपटाया जा सकता है 'upload.Page_Load (ऑब्जेक्ट, EventArgs) '। एक सिस्टम उत्पन्न करने से बचने के लिए। ऑब्जेक्ट डिस्प्ले अपवाद जिसे आप कॉल नहीं करना चाहिए किसी ऑब्जेक्ट पर एक से अधिक बार निपटाना।

using(var stream = File.Open(newFilename, FileMode.CreateNew)) 
using(var reader = new BinaryReader(file.InputStream)) 
using(var writer = new BinaryWriter(stream)) 
{ 
    var chunk = new byte[ChunkSize]; 
    Int32 count; 
    while((count = reader.Read(chunk, 0, ChunkSize)) > 0) 
    { 
     writer.Write(chunk, 0, count); 
    } 
} 

मुझे समझ में नहीं आता कि इसे दो बार क्यों कहा जा सकता है, और त्रुटि को खत्म करने के लिए इसे कैसे ठीक किया जाए। कोई मदद?

+1

आज तक, वीएस2017 प्रत्येक 'उपयोग' खंड के बारे में CA2202 फेंक रहा है। किसी को भी अपना कार्य मिलना होगा। – ajeh

उत्तर

6

बाइनरी रीडर/बाइनरीवाइटर आपके निपटारे के दौरान अंतर्निहित धारा का निपटान करेगा। आपको इसे स्पष्ट रूप से करने की आवश्यकता नहीं है।

इसे ठीक करने के लिए आप स्ट्रीम के चारों ओर उपयोग को हटा सकते हैं।

5

आपका लेखक हमेशा आपकी स्ट्रीम का निपटान करेगा।

13

समझने के लिए, अपने कोड

using(var stream = File.Open(newFilename, FileMode.CreateNew)) 
{ 
    using(var reader = new BinaryReader(file.InputStream)) 
    { 
     using(var writer = new BinaryWriter(stream)) 
     { 
      var chunk = new byte[ChunkSize]; 
      Int32 count; 
      while((count = reader.Read(chunk, 0, ChunkSize)) > 0) 
      { 
       writer.Write(chunk, 0, count); 
      } 
     } // here we dispose of writer, which disposes of stream 
    } // here we dispose of reader 
} // here we dispose a stream, which was already disposed of by writer 

इससे बचने के लिए संपादित करने के लिए, बस लेखक सीधे

using(var reader = new BinaryReader(file.InputStream)) 
    { 
     using(var writer = new BinaryWriter(File.Open(newFilename, FileMode.CreateNew))) 
     { 
      var chunk = new byte[ChunkSize]; 
      Int32 count; 
      while((count = reader.Read(chunk, 0, ChunkSize)) > 0) 
      { 
       writer.Write(chunk, 0, count); 
      } 
     } // here we dispose of writer, which disposes of its inner stream 
    } // here we dispose of reader 

edit बनाने के लिए: ध्यान में रखना क्या एरिक Lippert कह रहा है, वहाँ वास्तव में एक पल हो सकता है जब स्ट्रीम केवल अंतिमकर्ता द्वारा जारी की जाती है यदि बाइनरीवाइटर अपवाद फेंकता है। BinaryWriter कोड के अनुसार, कि तीन मामलों

If (output Is Nothing) Then 
     Throw New ArgumentNullException("output") 
    End If 
    If (encoding Is Nothing) Then 
     Throw New ArgumentNullException("encoding") 
    End If 
    If Not output.CanWrite Then 
     Throw New ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable")) 
    End If 
  • में हो सकता है अगर आप एक आउटपुट निर्दिष्ट नहीं किया है यानी अगर धारा रिक्त है। यह एक समस्या नहीं होनी चाहिए क्योंकि एक नल स्ट्रीम का मतलब है कि निपटान करने के लिए कोई संसाधन नहीं है :)
  • यदि आपने एन्कोडिंग निर्दिष्ट नहीं किया है। चूंकि हम कन्स्ट्रक्टर फॉर्म का उपयोग नहीं करते हैं जहां एन्कोडिंग निर्दिष्ट है, वहां कोई समस्या नहीं होनी चाहिए (मैंने एन्कोडिंग कन्स्ट्रक्टर को बहुत अधिक नहीं देखा है, लेकिन एक अवैध कोडपेज फेंक सकता है)
    • यदि आप ' एक लिखने योग्य धारा पारित करें। यही कारण है कि वैसे भी विकास के दौरान बहुत जल्दी पकड़ लिया जाना चाहिए ...

, अच्छा बिंदु, इसलिए संपादित :)

+2

अब आउटपुट स्ट्रीम खोले जाने के बाद नया बाइनरीवाइटर फेंकता है तो क्या होगा? तब धारा बंद कौन करता है? कोई भी नहीं, जब तक फाइनलर चलता है। व्यवहार में, यह बहुत अधिक नहीं होता है और व्यवहार में, भले ही ऐसा होता है, सबसे बुरा परिणाम यह है कि फ़ाइल थोड़ी देर तक खुलती रहती है। लेकिन अगर आपके तर्क * की आवश्यकता है * सभी संसाधन आक्रामक रूप से साफ किए जाएंगे चाहे कोई पागल अपवाद क्यों न हो, तो यह कोड सही नहीं है। –

+0

@Eric: हाँ वास्तव में, लेकिन चूंकि कक्षाओं में यह जांचने के लिए कोई रास्ता नहीं है कि फाइलस्ट्रीम पहले से बंद है, हम आसानी से इसे ध्यान में नहीं ले सकते हैं। अगर हमारे पास स्ट्रीम में बूलियन के रूप में बंद संपत्ति() थी, तो हम विशेष मामलों को संभालने के लिए फाइलस्ट्रीम में बंद तर्क जोड़ सकते हैं जहां बाइनरी राइटर कन्स्ट्रक्टर – samy

+0

में अपवाद होता है, विशेष रूप से, यदि मैं उपरोक्त कोड का उपयोग करता हूं, और कोड विश्लेषण चलाता हूं मुझे त्रुटि संदेश कह रहा है: कॉल सिस्टम .IDisposable। ऑब्जेक्ट 'फ़ाइल पर खोलें। खोलें (string.Concat (upload.BaseDir, newId, CS $ <> 8__locals3.suffix), FileMode.CreateNew)' सभी संदर्भों से पहले यह दायरे से बाहर हैं। –

5

निपटान का एक उचित कार्यान्वयन स्पष्ट रूप से देखभाल करने के लिए नहीं है, तो इसे और अधिक बुलाया गया है की आवश्यकता होती है एक ही वस्तु पर एक बार से अधिक। जबकि निपटान के लिए कई कॉल कभी-कभी तर्क समस्याओं या कोड का संकेत देते हैं जिन्हें बेहतर लिखा जा सकता है, मूल पोस्ट कोड में सुधार करने का एकमात्र तरीका यह है कि माइक्रोसॉफ्ट को बाइनरी रीडर और बाइनरीवाइटर को एक विकल्प जोड़ने के लिए प्रोत्साहित करना होगा ताकि उन्हें उनके पास- स्ट्रीम में (और उसके बाद उस विकल्प का उपयोग करें)। अन्यथा, फ़ाइल को बंद करने के लिए आवश्यक कोड, भले ही पाठक या लेखक अपने कन्स्ट्रक्टर में फेंक देता है, पर्याप्त रूप से बदसूरत होगा कि फ़ाइल को एक से अधिक बार डिस्पोजेक्ट करने के लिए क्लीनर प्रतीत होता है।

10

मैंने इस समस्या से संघर्ष किया और उदाहरण के लिए here उदाहरण बहुत उपयोगी पाया।मैं एक त्वरित दृश्य के लिए कोड पोस्ट करेंगे:

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate)) 
{ 
    using (StreamWriter writer = new StreamWriter(stream)) 
    { 
     // Use the writer object... 
    } 
} 

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

Stream stream = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.OpenOrCreate); 
    using (StreamWriter writer = new StreamWriter(stream)) 
    { 
     stream = null; 
     // Use the writer object... 
    } 
} 
finally 
{ 
    if(stream != null) 
     stream.Dispose(); 
} 

ऐसा करने से मेरी त्रुटियों को मंजूरी मिल गई।

+0

है और एमएसडीएन लिंक के लिए धन्यवाद। – Jedidja