.net प्रयास में अंत में क्यों उपयोग करें... पकड़ो




vb.net exception-handling (12)

जो मैं अक्सर उपयोग करता हूं वह है (मैंने इसे एक पहलू में encapsulated, लेकिन यह है कि मैं पहलू से व्युत्पन्न):

public static DoLengthyProcessing(this Control control, Action<Control> action)
{
    Cursor oldCursor = control.Cursor
    try
    {
        control.Cursor = Cursors.WaitCursor;
        action(control);
    }
    catch (Exception ex)
    {
        ErrorHandler.Current.Handler(ex);
    }
    finally
    {
        control.Cursor = oldCursor;
    }
}

या, एओपी का उपयोग करें (जैसा कि मैं करता हूं)।

मैं देखता हूं कि Finally में Try .. Catch की कोशिश ब्लॉक के निष्पादन के किसी भी हिस्से के बाद Try .. Catch हमेशा निष्पादित होगा।

क्या Finally अनुभाग को छोड़ने के लिए यह अलग है और इसे पकड़ने के प्रयास के बाहर, बस इसे चलाने के बाद?

उदाहरण 1, कोशिश करें ... पकड़ो ... आखिरकार ... कोशिश करें

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    Finally
        'Do cleanup
    End Try

उदाहरण 2, कोशिश करें ... पकड़ो ... अंत कोशिश करें ... आखिर में बाहर की चीजें करें

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    End Try
    'Do cleanup

जहां तक ​​मुझे याद है मैंने कभी भी अपने .NET कोड में कोशिश / पकड़ / आखिरकार ब्लॉक का उपयोग नहीं किया है।

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

तो मध्य स्तर में आप अक्सर कोशिश / आखिरकार (या "उपयोग" कथन) देखेंगे ताकि संसाधन साफ ​​हो जाएं। और प्रस्तुतिकरण स्तर में शीर्ष-स्तर हैंडलर में प्रयास / पकड़ने में।

दुर्लभ मामलों में मुझे दोनों को अपवाद पकड़ने और कुछ सफाई करने की आवश्यकता है, मैं प्रतिबिंबित करना पसंद करूंगा ताकि निम्नलिखित:

try
{
    ... do something
}
catch
{
   ... handle exception
}
finally
{
   ... cleanup
}

हो जाता है:

try
{
    DoSomethingAndCleanup();
}
catch
{
   ... handle exception
}

...
private void DoSomethingAndCleanup()
{
    try
    {
        ... do something
    }
    finally
    {
        ... cleanup
    }
}

आईएमएचओ यह बहुत साफ है।


अंत में कोड शामिल है जिसे सभी शर्तों पर मूल्यांकन किया जाना चाहिए [चाहे कोई अपवाद हुआ हो या नहीं]।

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

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

संपादित करें

अंततः एक स्टैक ओवरफ्लो अपवाद के बाद निष्पादित नहीं किया जाएगा।


अंत में ब्लॉक में साफ करना यह सुनिश्चित करना है कि यह चल रहा है। यदि पकड़ ब्लॉक अपवाद से निपटता नहीं है (यानी यह सिर्फ इसे लॉग करता है), या यहां तक ​​कि एक और अपवाद भी उत्पन्न करता है, तो अंत में ब्लॉक में कोड अभी भी चलाएगा।


प्रयास पकड़ने के ब्लॉक के निष्पादन के किसी भी हिस्से के बाद पकड़ नहीं चलेगा। कैच केवल तभी चलाया जाएगा जब कोई अपवाद फेंक दिया जाता है और कैच ब्लॉक उस प्रकार के अपवाद को संभाल सकता है।

आखिरकार ब्लॉक वह है जो कोशिश करेगा जब कोशिश ब्लॉक पूरा हो जाएगा। पूरी तरह से, मेरा मतलब है कि यह सामान्य रूप से समाप्त होता है, या किसी भी तरह से बाहर निकलता है (एक लूप से बाहर तोड़ता है, विधि से रिटर्न, अपवाद फेंकता है, आदि)

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

असल में, अंत में ब्लॉक में साफ किया जाना चाहिए।


हाँ, यह अलग है। अंत में हमेशा चलेंगे (प्रोग्राम क्रैश को छोड़कर)। यदि फ़ंक्शन कैच ब्लॉक के अंदर निकलता है, या किसी अन्य त्रुटि को या तो कोशिश या पकड़ में फेंक दिया जाता है, तो अंत में अभी भी निष्पादित होगा। आपको अंततः कथन का उपयोग न करने वाली कार्यक्षमता नहीं मिलेगी।


हर किसी ने जो कहा, उसके ऊपर, अर्थात् मुझे लगता है कि वे अलग हैं।

अंत में ब्लॉक में कोड स्पष्ट रूप से बताता है कि आप कोशिश-पकड़ के भीतर निहित सामग्री के लिए अंतिमकरण प्रकार कार्य कर रहे हैं। मुझे लगता है कि यह पढ़ने के लिए स्पष्ट बनाता है।


डेटाबेस कनेक्शन या किसी भी समय ऑब्जेक्ट्स से निपटने के दौरान यह एक अच्छा विचार है। प्रश्नों के दौरान कुछ गलत होने पर, आप अभी भी कनेक्शन को सुरक्षित रूप से बंद कर सकते हैं। यह कोड को साफ करने में भी मदद करता है कि कोशिश / पकड़ / अंत में ब्लॉक के बाहर ब्लॉक तक पहुंचने में सक्षम नहीं है।


चार रेडियो बटन के साथ कोड:

  • कोशिश में वापसी
  • कैच में वापसी
  • कैच में फेंको
  • कैश खत्म करो

    private void checkFinally()
    {
        try
        {
            doFinally();
        }
        catch
        {
            Console.WriteLine(" Breaking news: a crash occured. ");
        }
    }
    
    private void doFinally()
    {
        Console.WriteLine(" ");
        Console.Write("Here goes: " 
            + (radioReturnInTry.Checked ? "2. Return in try: " 
                    : (radioReturnInCatch.Checked? "3. Retrun in catch: "
                        : (radioThrowInCatch.Checked? "4. Throw in catch: "
                            : "1. Continue in catch: "))) );
        try
        {
            if (radioReturnInTry.Checked)
            {
                Console.Write(" Returning in try. ");
                return;
            }
            Console.Write(" Throwing up in try.  ");
            throw new Exception("check your checkbox.");
        }
        catch (Exception ex)
        {
            Console.Write(" ...caughtcha! ");
            if (radioReturnInCatch.Checked)
            {
                Console.Write("Returning in catch. ");
                return;
            }
            if (radioThrowInCatch.Checked)
            {
                Console.Write(" Throwing up in catch. ");
                throw new Exception("after caught");
            }
        }
        finally { Console.Write(" Finally!!"); }
        Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, 
        // this would never happen (and was marked grey by ReSharper)
    
    }
    

आउटपुट:

  • यहां जाता है: 1. पकड़ में जारी रखें: कोशिश में फेंकना। ... caughtcha! आखिरकार!! किया हुआ!!!
  • यहां जाता है: 2. कोशिश में वापसी: कोशिश में लौट रहा है। आखिरकार!!
  • यहां जाता है: 3. पकड़ने में पुनः प्रयास करें: कोशिश में फेंकना। ... caughtcha! पकड़ में वापसी आखिरकार!!
  • यहां जाता है: 4. पकड़ने में फेंको: कोशिश में फेंकना। ... caughtcha! पकड़ में फेंकना आखिरकार!! ब्रेकिंग न्यूज: एक दुर्घटना हुई।

संक्षेप में: अंत में दो चीजों का ख्याल रखता है:

  1. कोशिश में या पकड़ में लौटने वाले कोड का।
  2. या यदि आप कोशिश में अपवाद था, और पकड़ में एक अपवाद थ्रो,
  3. या, यदि आपके पास प्रयास में अपवाद था, और उस अपवाद को कैट नहीं किया गया था,

अंत में "अंतिम रूप से" सारांशित करने के लिए : अंत में कुछ भी विशेष नहीं है यदि आपने कोशिश की, और

  1. वापस नहीं किया गया,
  2. और परीक्षण के दौरान, और फिर किसी भी अपवाद पकड़ा
  3. पकड़ में वापसी न करें, और
  4. नहीं थ्रो या कोड जो फेंकता है।

और आखिरी लेकिन कम से कम नहीं (आखिरकार): यदि आपके कोड में अपवाद है जिसे आपने कैच नहीं किया है, तो आपका कोड उड़ जाएगा, अंतिम रूप से पहुंचने के बिना।

उम्मीद है कि यह स्पष्ट है। (अब यह मेरे लिए है ...)

मोशे


अंत में एक प्रणाली को सुसंगत रखने के लिए हर चीज के लिए इस्तेमाल किया जाना चाहिए। इसका आमतौर पर रिहाई संसाधनों का मतलब है

आखिर में हमेशा निष्पादित किया जाता है, इससे कोई फर्क नहीं पड़ता कि अपवाद फेंक दिया गया था। निम्नलिखित मामलों में संसाधनों को जारी करने के लिए इसका इस्तेमाल किया जाना चाहिए:

  • एक कनेक्शन को अंतिम रूप दें
  • एक फ़ाइल हैंडलर बंद करें
  • फ्री मेमोरी
  • डेटाबेस कनेक्शन बंद करें

मुझे एक पूरा उदाहरण दें। कल्पना कीजिए कि आप नेटवर्क के माध्यम से संदेश भेज रहे हैं। छद्म कोड में:

// With finally                  |  //Without finally
try{                             |  try{  
  send_message()                 |    send_message() 
} catch(NetworkError){           |  } catch(NetworkError){ 
  deal_with_exception()          |    deal_with_exception()
} finally {                      |  }
  finalizes_connection()         |  finalizes_connection() 
}                                |

दोनों कोडों का एकमात्र अंतर यह है कि जब try ब्लॉक में क्या होता है तो अपवाद उठाता है जो NetworkError MethodNotFound नहीं है, उदाहरण के लिए, MethodNotFound । पहले मामले में, विधि finalizes_connection() को कॉल किया जाएगा, और दूसरे में, यह नहीं होगा।

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

यह एक फ़ाइल के लिए भी लागू होगा, उदाहरण के लिए, आपने खोला है और अन्य प्रोग्राम पढ़ने (विंडोज़ में) के लिए खोलने में सक्षम नहीं होंगे। और स्मृति के लिए, इसे कभी जारी नहीं किया जाता है और अब आपके पास स्मृति रिसाव है।


आप अंततः क्लीनअप कोड के लिए उपयोग करते हैं, उदाहरण के लिए डीबी कनेक्शन या फाइलें जो खुले हैं जिन्हें बंद होने की आवश्यकता है। वस्तुतः कोई भी सफाई कोड जिसे अपवाद के बावजूद निष्पादित करने की आवश्यकता है या नहीं

साथ ही, आपके अपवाद हैंडलिंग को अपवाद, या अन्य अपवाद को फिर से फेंकने की आवश्यकता हो सकती है, इस स्थिति में ब्लॉक के बाद कोड निष्पादित नहीं किया जाएगा


अंतर यह है कि try ब्लॉक में कोड एक अपवाद फेंकता है जो catch ब्लॉक द्वारा पकड़ा नहीं जाता है।

आम तौर पर एक catch ब्लॉक एक विशिष्ट प्रकार के अपवाद को पकड़ लेगा, और कुछ और के माध्यम से चलो। उस स्थिति में, finally ब्लॉक अभी भी चल जाएगा।

finally ब्लॉक भी चलाएगा यदि try ब्लॉक में कोड return





try-catch-finally