2013-06-07 3 views
6

मैंने कुछ कोडों में बस ठोकर खाई है जो GC.KeepAlive() विधि का उपयोग करती हैं और मैं यह समझने की कोशिश कर रहा हूं कि यह कैसे काम करता है। उदाहरण के लिए, इस कोड में:कचरा कलेक्टर KeepAlive विधि टाइमर के साथ कैसे काम करता है?

Timer timer = new System.Timers.Timer(5000); 
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
timer.Enabled = true; 
GC.KeepAlive(timer); 

इस कोड में, मैं समझता हूँ कि एक टाइमर वस्तु बनाई गई है, जो एक धागा है कि हर 5 सेकंड चलाता spawns है। अगला, जीसी लाइन भाग गया है। तब विधि बाहर निकलती है, कचरा संग्रह चलाने पर टाइमर को नष्ट कर देता है।

KeepAlive केवल KeepAlive को कॉल से पहले जीवित रखता है, जो मुझे लगता है कि यह लगभग 0.0000001 सेकेंड है और इसे किसी भी तरह से स्थानीय संदर्भ नहीं होने के कारण वहां नष्ट नहीं किया जाएगा (जब तक कि यह इसे नष्ट नहीं कर रहा है क्योंकि कुछ भी नहीं टाइमर ऑब्जेक्ट के साथ होता है?)

किसी भी तरह से, जब तक 5000 अंतराल मारा जाता है, तब तक विधि पहले समाप्त हो जाएगी और टाइमर नष्ट हो जाने की संभावना है। तो उस लाइन का उद्देश्य क्या है?

+1

मूल डेवलपर से पूछें? – dtb

+0

जब तक आप प्रबंधित कोड से निपट रहे हैं (यानी पूरी तरह से .NET में), 'GC.KeepAlive' का उपयोग करने की कोई आवश्यकता नहीं है। यह सब टाइमर ऑब्जेक्ट का संदर्भ रखता है, इसलिए यह कचरा नहीं होगा। [दस्तावेज़] (http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx) का कहना है कि यह वास्तव में प्रबंधित कोड में आवंटित ऑब्जेक्ट्स के उपयोग के लिए है जिसका उपयोग अप्रबंधित कोड (जैसे एक Win32 एपीआई कॉल)। तो इस विशेष उदाहरण के लिए, यह व्यर्थ लगता है। – ThatBlairGuy

+1

अफसोस की बात है कि मूल डेवलपर लंबे समय से चला गया है, और मुझे बनाए रखने के लिए एक परियोजना की यह सुंदरता छोड़ दी है :) – NibblyPig

उत्तर

4

तो उस पंक्ति का उद्देश्य क्या है?

कुछ भी नहीं। आपको इसका उपयोग नहीं करना चाहिए क्योंकि यह कुछ भी मदद नहीं कर रहा है। वह कोड शायद किसी ऐसे व्यक्ति द्वारा लिखा गया था जो विशेष रूप से Timer कक्षा के कामों से परिचित नहीं है।

आंतरिक रूप से Timer कक्षा यह सुनिश्चित करने के पूरी तरह से अलग माध्यमों का उपयोग करेगी कि यह कचरा नहीं होने से पहले एकत्र किया जाना चाहिए। विवरण के लिए this question देखें।

+1

यह भी: http://stackoverflow.com/questions/4959149/do-timer-object-get-gc-ed-when-no-other-object-references-them –

+0

दिलचस्प। मुझे आश्चर्य है कि यह System.Timers.Timer (जो ओपी उपयोग कर रहा है) और सिस्टम के लिए सच है। थ्रेडिंग। टिमर। मुझे याद है कि कम से कम, थ्रेडिंग टाइमर एकत्र किया जाएगा। इसे शोध करना होगा। ... और मेरे प्रश्न का उत्तर: http: // stackoverflow।कॉम/क्यू/4962172/56778 –

+1

@ जिम मिशेल परीक्षण करना बहुत आसान है। कुछ नमूना कार्यक्रमों ने संकेत दिया है कि न तो system.timers.timer और न ही system.threading.timer निष्पादित करते समय एकत्र किया जाएगा। – Servy

1

इस संदर्भ में, उस लाइन के लिए कोई कारण नहीं है।

timer.Enabled = true; 
    // lots of code here that does 
    // things that take some time 
    GC.KeepAlive(timer); 
} 

कि टाइमर इकट्ठा करने से पहले विधि समाप्त होता है से कचरा कलेक्टर पाएगा: अगर वहाँ के रूप में timer.Enabled और KeepAlive करने के लिए कॉल के बीच कोड का एक बहुत कुछ है केवल समय यह मदद कर सकते हैं। KeepAlive पर कॉल किए बिना, जीसी यह तय कर सकता है कि timer का उपयोग Enabled सेट के बाद और नहीं किया गया है, और यह प्रारंभिक संग्रह कर सकता है।

यदि आप लगातार टाइमर चाहते हैं, तो आपको इसे कक्षा के दायरे में घोषित करना होगा।

+0

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

+0

@AndreasReiff: Servy का जवाब सही है, जैसा कि मैंने अपने प्रश्न पर मेरी टिप्पणी में बताया था। मैंने एक प्रश्न का एक लिंक भी प्रदान किया जो प्रश्न का एक बहुत विस्तृत उत्तर प्रदान करता है। –

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