2010-03-17 15 views
11

बहुत समय पहले सी/सी ++ से आ रहा है, मुझे अभी भी यह सुनिश्चित करने की आदत है कि सभी संसाधन सही तरीके से साफ हो गए हैं। मैं हमेशा यह सुनिश्चित करता हूं कि डिस्पोजेक्ट को आईडीस्पोज़ेबल क्लास पर बुलाया जाता है और डिस्पोजेबल ऑब्जेक्ट्स वाले मेरे वर्गों में डिस्पोजेक्ट पैटर्न को कार्यान्वित करता है।IDISposable, क्या यह वास्तव में

हालांकि, मेरे पर्यावरण में मैं केवल इतना ही कम कर रहा हूं। अन्य सिर्फ यह नहीं समझते कि मैं क्या कर रहा हूं और सोचता हूं कि मेरा कोड समझना अधिक कठिन है।

वे बंद या निपटान के बिना डेटाबेस कनेक्शन, खुली धाराएं आदि बनाते हैं। कभी-कभी वे किसी विधि के अंत में स्थानीय या सदस्य चर को "कुछ भी नहीं" पर सेट करते हैं (उनकी पृष्ठभूमि अनुमान लगाएं)।

मेरी समस्या यह है कि उनका कोड बस के साथ ही मेरा काम करता है। कोड जो समय के साथ हजारों डेटाबेस कनेक्शन ऑब्जेक्ट बनाता है बस काम करता है।

तो,, कोड शुद्धता के बारे में कोई बहस, दिशा निर्देशों आदि निम्नलिखित अनदेखी IDiposable वास्तव में करता है बात?

क्या कोई वास्तव में वस्तुओं का निपटान न करने से संसाधनों से बाहर हो गया है?

संपादित करें: सभी उत्तरों के लिए धन्यवाद। यह देखने में दिलचस्प है कि निपटान नहीं करते समय कुछ लोगों को समस्याएं थीं। हालांकि यह दुर्लभ प्रतीत होता है और मुझे लगता है कि जीसी/जेआईटी सामान्य परिस्थितियों में संसाधनों के उपयोग को कम रखने का अच्छा काम करता है।

न तो मेरे सहयोगी और न ही मैं इस वजह से व्यवहार बदल दूंगा लेकिन यह सही होने के लिए अच्छा लगता है।

+1

एसओ पर कई समस्याएं "अजीब चीजें होती हैं" विविधता के हैं। मुझे लगता है कि उनमें से आधा निपटान करने में असफल होने के कारण हैं, खासकर यदि वे केवल दूसरे या बाद के समय किसी प्रकार के लूप के माध्यम से होते हैं। दूसरा आधा अनचाहे अपवाद हैं, बीटीडब्ल्यू। –

+0

मैंने दूसरों के साथ IDISposible पैटर्न का उपयोग करने के लिए एक ही तर्क दिया है और एक समान प्रतिक्रिया प्राप्त की है। आप इस संघर्ष में निश्चित रूप से अकेले नहीं हैं। मैं आपको बताता हूं कि आप जो जानते हैं उससे समझौता नहीं करना सही और उचित है क्योंकि आपका कोड "पढ़ने में मुश्किल" है। बस मेरे 2 सेंट। –

+2

यदि कुछ और नहीं है, तो __explicit__ भाषा –

उत्तर

26

हां, मैंने कनेक्शन ऑब्जेक्ट पर लूप करते समय ओरेकल कर्सर की संख्या को अधिकतम कर दिया है, उदाहरण के लिए, क्योंकि मैं कमांडर को बंद करना भूल गया था - यह एक कनेक्शन पर केवल 100 लूप भी था, और मुझे इसकी आवश्यकता थी समर्थन करें कि संभवतः सैकड़ों कनेक्शन एक ही समय में कर रहे हैं।

आपका साथी डेवलपर using() { ... } syntax उपयोग करने के लिए अगर वे खुद को किसी भी अप्रबंधित संसाधनों को बंद करने के लिए परेशान नहीं किया जा सकता है सिखाया जाना चाहिए। यह वैसे भी अच्छा अभ्यास है और आपको इसका भी उपयोग करना चाहिए, क्योंकि आप अपने Dispose() को finally {} क्लॉज में कॉल करना भूल सकते हैं ताकि वास्तव में एक अनचाहे अपवाद को फेंकने की स्थिति में साफ हो सके।

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

+4

+1। –

1

डेटाबेस कनेक्शन का निपटान (या बंद नहीं) अंततः आपको काट देगा, हाँ। मैंने देखा है कि ऐसा होता है।

+0

@ एनन-डाउनवॉटर "क्या कोई वास्तव में वस्तुओं का निपटान न करने से संसाधनों से बाहर हो गया है?" मेरी प्रतिक्रिया इस प्रश्न का सीधा जवाब है कि निबंध की आवश्यकता नहीं है, कम से कम अपने दोषपूर्ण तर्क को समझाएं। – heisenberg

4

हैंडल जैसे कुछ संसाधन पूरे सिस्टम के लिए सीमित संसाधन हैं, इसलिए यदि आपका एप्लिकेशन इन अन्य अनुप्रयोगों को जारी नहीं करता है या ओएस भी पीड़ित हो सकता है। उदाहरण के लिए विंडोज श्रृंखला की सीमाओं को धक्का देने में मार्क रसेलिनोविच के latest article पर एक नज़र डालें।

0

मेरे पास ऐसा मामला था जिसे मैं दुर्भाग्य से विवरण याद नहीं कर सकता, लेकिन यह किसी प्रकार की स्तरित धाराओं थी।lowerlevel फ़ाइल धारा कभी कभी से पहले upperlevel पाठ फ़ॉर्मेटर, प्लावित किया गया था जिसके कारण पिछले उत्पादन पाठ फ़ॉर्मेटर को पत्र लिखा खो जाने की बंद हो गया।

3

हां, मैं कनेक्शन ऑब्जेक्ट्स के साथ एक ओरेकल डेटाबेस में निपटान नहीं कर रहा था।

ऊपर माइक एटलस का मुद्दा खराब है, लेकिन यह गलत होने के बारे में कम से कम स्पष्ट था। मुद्दा हम में भाग था उस समय से भारी बोझ के नीचे समय पर, साइट जब हम एक कनेक्शन खोलने की कोशिश की त्रुटियों फेंकने शुरू होगा, लेकिन समय हम प्रणाली यह सब मंजूरी दे दी है (क्योंकि garabe कलेक्टर मंजूरी दे दी को देखा द्वारा वस्तुओं और कनेक्शन पूल मुक्त कर दिया)। यह पुन: पेश करने के लिए बहुत मुश्किल था जब तक मैं कोड के माध्यम से देख रहा था और पाया है कि एक कनेक्शन एक त्रुटि की स्थिति में बंद किया जा रहा नहीं कर रहा था, एक using बयान को यह बदल रहा है पूरे मुद्दे तय की।

संक्षिप्त उत्तर यह है कि यदि कोई ऑब्जेक्ट IDISposable को लागू करने का प्रयास करता है, तो यह एक कारण के लिए है, इसलिए जब आप पूरा कर लें तो हमेशा इसे निपटें, आदर्श रूप से using कथन के साथ। चतुर या कभी कभी नहीं बल्कि दूसरी बार जब आपको लगता है कि आप ऐसा ऐसा करने की आवश्यकता है निपटाने के साथ मुश्किल हो न करें। बस हर बार क्या काम करता है।

छोटा, और अधिक संतोषजनक उत्तर यह है कि आप सही हैं, और आपके सहकर्मी मूर्ख हैं जो नहीं जानते कि वे क्या कर रहे हैं।

5

हां यह महत्वपूर्ण है। जब कोई ऑब्जेक्ट IDISposable लागू करता है तो यह स्पष्ट रूप से बताता है कि यह उन संसाधनों को पकड़ रहा है जिन्हें ऑब्जेक्ट की आवश्यकता नहीं होने पर रिलीज़ होने की आवश्यकता है।

ऑब्जेक्ट को अंतिम रूप देने पर अधिकांश संसाधन अभी भी अपने संसाधनों को साफ़ कर देंगे लेकिन अंतिम रूप निर्धारित नहीं है और संसाधन प्रबंधन के लिए भरोसा नहीं किया जा सकता है।

बस using(...) ब्लॉक में परिवर्तनीय घोषणाओं को लपेटने से यह ठीक से निपटना आसान हो जाता है।

0

डेटाबेस जारी किए गए IDISposable ऑब्जेक्ट्स का निपटान नहीं करना वातावरण में OutOfMemoryExceptions उत्पन्न करने के लिए एक विश्वसनीय और प्रभावी तरीका है।

डेटासेट आईडीस्पोज़ेबल लागू करता है और मैंने पढ़ा है कि डेटा को डिस्प्ले करने की आवश्यकता नहीं है क्योंकि डेटासेट के लिए डिस्प्ले करने वाली वस्तुओं को केवल डिज़ाइन समय (दृश्य स्टूडियो डिजाइनर द्वारा) पर बनाया जाता है। मैंने कभी भी ओओएम को गैर-डिस्प्लेड डेटासेट्स से नहीं देखा है (केवल विशाल डेटासेट्स से ओओएम)

0

संसाधनों के स्पष्ट मामलों (पहले से ही उल्लेख किए गए) के अलावा, आईडीस्पोजेबल का एक अन्य लाभ यह है कि, क्योंकि यह गारंटी देता है कि निपटान() है कहा जाता है जब एक using ब्लॉक बाहर निकलता है, आप चीजों के सभी प्रकार के लिए उपयोग कर सकते हैं, यहां तक ​​कि चीजें हैं जो न सिर्फ "ओएस संसाधन के साथ कार्रवाई करने" कर रहे हैं।

इस तरह, यह रूबी ब्लॉक के लिए एक गरीब व्यक्ति के विकल्प की तरह है, या लिस्प मैक्रोज़ के एक छोटे से उपयोग के मामले के लिए है।

0

हाँ, हाँ, हाँ, यह महत्वपूर्ण है।

मैं हाल ही में एक आवेदन प्रोफाइल कर रहा हूं जिसे कभी प्रोफाइल नहीं किया गया था। यह सिर्फ एक Winforms आवेदन, कोई बड़ी बात नहीं, ठीक है?

गलत।

आईडीस्पोजिबल लागू नहीं कर रहा है और डी-रेफरेंसिंग ईवेंट हैंडलर नहीं, एप्लिकेशन एक चलनी की तरह स्मृति लीक कर रहा था।

.NET Framework आपको स्वयं के बाद सफाई करने से नहीं रोकता है, यह केवल कम संभावना है कि अगर आप ऐसा नहीं करेंगे तो आप कुछ तोड़ देंगे।

एक घंटे बिताएं, ANTS Profiler के साथ अपना आवेदन प्रोफाइल करें। यह एक नि: शुल्क परीक्षण है। यदि आपको कोई मेमोरी लीक नहीं दिखाई देती है, तो अपने रास्ते पर जारी रखें। यदि आप करते हैं, तो ऐसा इसलिए होता है क्योंकि आप अपने क्रच होने के लिए .NET Framework पर भरोसा कर रहे थे।

+0

मुझे सिद्धांत पता है लेकिन क्या डेस्कटॉप पर वास्तव में स्मृति समस्याएं हैं? (सर्वर अनुप्रयोग एक अलग मामला है) रैम के गीगाबाइट के साथ उपलब्ध होने से पहले इसे लंबे समय तक लग जाएगा। – adrianm

+1

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

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