2012-05-22 15 views
7

मैं "माइक्रोसॉफ्ट मिनिमल नियम" कोड विश्लेषण सेट के साथ अपने प्रोजेक्ट का निर्माण कर रहा हूँ और यह मेरे इस पद्धति पर CA2000 देता है:इस विधि क्यों कारण नहीं संहिता विश्लेषण त्रुटि CA2000: निपटान() कॉल

private Timer InitializeTimer(double intervalInSeconds) 
{ 
    Timer timer = null; 

    try 
    { 
     timer = new Timer { Interval = intervalInSeconds * 1000, Enabled = true }; 
     timer.Elapsed += timer_Elapsed; 
     timer.Start(); 
    } 
    catch 
    { 
     if (timer != null) 
     { 
      timer.Dispose(); 
     } 
    } 
    return timer; 
} 

यह विधि केवल सेकंड में अंतराल से एक नया System.Timers.Timer बनाता है। मेरे पास तीन ऐसे टाइमर चल रहे हैं (प्रत्येक सेकेंड के लिए एक, एक मिनट और हर आधे घंटे)। हो सकता है कि एक टाइमर होना बेहतर हो और विलुप्त होने वाले ईवेंट हैंडलर में जांच करें कि क्या डेढ़ घंटे बीत चुका है, लेकिन मुझे नहीं पता, यह इस समय आसान है, यह विरासत कोड है और मैं सबकुछ तोड़ना नहीं चाहता अभी तक।

इस विधि को पकड़ने में मुझे बदनाम

Warning 21 CA2000 : Microsoft.Reliability : In method 'TimerManager.InitializeTimer(double)', call System.IDisposable.Dispose on object '<>g__initLocal0' before all references to it are out of scope. 

अब मैं बोल रहा हूँ निपटान देता है और यह पर्याप्त होगा सोचा है? मैं कक्षा के अपने आईडीएसओएसपीबल कार्यान्वयन में सभी टाइमर का निपटान भी कर रहा हूं।

मुझे यहां क्या याद आ रही है?

+4

ऑब्जेक्ट प्रारंभकर्ता वाक्य रचना बाहर ले बेहतर है - कि क्या चेतावनी (के बाद से वस्तु मौजूद है, का निर्माण किया ट्रिगर है, लेकिन प्रारंभकर्ता द्वारा चलाए जाने पर 'टाइमर' को असाइन नहीं किया गया है। मैं डुप्लिकेट प्रश्न ढूंढने की कोशिश कर रहा हूं जो इस से संबंधित है। –

+1

[डुप्लिकेट का उपयोग करने में ऑब्जेक्ट प्रारंभकर्ता कोड विश्लेषण चेतावनी CA2000 उत्पन्न करता है] (http://stackoverflow.com/प्रश्न/3514902/ऑब्जेक्ट-प्रारंभकर्ता-इन-उपयोग-ब्लॉक-जनरेट-कोड-विश्लेषण-चेतावनी-ca2000) –

+3

ठीक है, शुरुआती सिंटैक्स को एक गूंगा उपकरण के लिए फेंक न दें। चेतावनी फर्जी है, वहां है स्टार्ट() को तब तक निपटाने के लिए कुछ भी नहीं कहा जाता है। अपवादों को निगलने और एक निस्तारण वस्तु को वापस करने, अब * वह * शिकायत करने के लिए कुछ होगा। –

उत्तर

2

अपवाद के मामले में आप केवल Dispose पर कॉल करते हैं (जिसे आपको कैच-ऑल ब्लॉक बीटीडब्लू के साथ कभी भी संभालना नहीं चाहिए, लेकिन यह एक और कहानी है)। कोई अपवाद नहीं होने पर, आप Timer ऑब्जेक्ट का निपटान नहीं करते हैं।

या तो finally ब्लॉक जोड़ें और Dispose पर जाएं, या using ब्लॉक का उपयोग करें।

+0

चूंकि टाइमर "अपवाद" पर वापस आ गया है, क्या यह ठीक नहीं होना चाहिए? या फिर, इसे हमेशा * क्यों निपटाया जाना चाहिए? –

+0

ठीक है, लेकिन मैं चाहता हूं कि टाइमर विधि के पीछे जीवित रहे, क्योंकि इसे मेरी कक्षा में किसी क्षेत्र में असाइन किया जा रहा है। मैं IDISposable कार्यान्वयन में अपने क्षेत्रों का निपटान कर रहा हूँ। मेरी कोशिश-पकड़ चेतावनी को दबाने का प्रयास था। – Davio

+0

@pst हां, यह ठीक होना चाहिए, लेकिन CodeAnalysis इसे पहचान नहीं सकता है। आप उस विशेष घटना को तब दबा सकते हैं। –

1

चेतावनी आपको बताती है कि आप एक डिस्पोजेबल ऑब्जेक्ट बना रहे हैं और सभी मामलों में इसका निपटारा नहीं कर रहे हैं। यदि आप इसे किसी अन्य विधि में ठीक से निपट रहे हैं, तो आप सुरक्षित रूप से इस चेतावनी को दबा सकते हैं (आप SuppressMessageAttribute का उपयोग करके ऐसा कर सकते हैं)।

+0

यही वह है जो मैं अन्य मामलों (यूनिटी के लाइफटाइम मैनेजर) में कर रहा हूं, लेकिन इससे पहले कि मैं इसे यहां कर रहा हूं, पहले जांचना चाहता हूं। – Davio

+0

हाँ, मुझे टाइमर जैसे लंबे समय से चलने वाली वस्तुओं के साथ अक्सर यह चेतावनी मिलती है। यह आपको यह बताने के लिए है कि आपको ऑब्जेक्ट को कहीं और निपटाना होगा। –

1

ठीक है, मैं इसे इस तरह संपादित:

private Timer InitializeTimer(double intervalInSeconds) 
    { 
     Timer tempTimer = null; 
     Timer timer; 
     try 
     { 
      tempTimer = new Timer(); 
      tempTimer.Interval = intervalInSeconds * 1000; 
      tempTimer.Enabled = true; 
      tempTimer.Elapsed += timer_Elapsed; 
      tempTimer.Start(); 
      timer = tempTimer; 
      tempTimer = null; 
     } 
     finally 
     { 
      if (tempTimer != null) 
      { 
       tempTimer.Dispose(); 
      } 
     } 
     return timer; 
    } 

यह प्रति CA2000 डॉक्स है और यह एक चेतावनी नहीं देता है। मैंने इस तथ्य को अनदेखा कर दिया था कि ऑब्जेक्ट प्रारंभकर्ता वाक्यविन्यास एक अस्थायी वस्तु बनाता है जिसे निपटान नहीं किया जा सकता है।

धन्यवाद, दोस्तों!

+0

आप अंततः रीथ्रो के साथ पकड़ने के लिए इसे बदलना चाहते हैं। अन्यथा, आप विधि से इसे वापस करने से पहले अपने टाइमर का निपटान करने जा रहे हैं, भले ही कोई अपवाद नहीं डाला गया हो। –

+0

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

-1

मुझे लगता है कि इसका इस्तेमाल करने के बजाय "की कोशिश/अंत में" "का उपयोग कर" reference

private Timer InitializeTimer(double intervalInSeconds) 
{ 
    Timer timer; 
    using (var tempTimer = new Timer()) 
    { 
     tempTimer.Interval = intervalInSeconds * 1000; 
     tempTimer.Enabled = true; 
     tempTimer.Elapsed += timer_Elapsed; 
     tempTimer.Start(); 
     timer = tempTimer; 
    } 
    return timer; 
}