c# - अगर मैं कोशिश ब्लॉक में एक मूल्य वापस करता हूं तो आखिरकार कथन आग में कोड होगा?




.net exception-handling (8)

99% परिदृश्यों की गारंटी होगी कि finally ब्लॉक के अंदर कोड चलाएगा, हालांकि, इस परिदृश्य के बारे में सोचें: आपके पास एक थ्रेड है जिसकी try -> finally ब्लॉक (कोई catch नहीं) और आपको उसमें एक अनचाहे अपवाद मिलता है धागा। इस मामले में, धागा बाहर निकल जाएगा और इसके finally ब्लॉक निष्पादित नहीं किया जाएगा (एप्लिकेशन इस मामले में चलना जारी रख सकता है)

यह परिदृश्य बहुत दुर्लभ है, लेकिन यह केवल यह दिखाने के लिए है कि उत्तर हमेशा "हां" नहीं होता है, यह ज्यादातर समय "हां" और कभी-कभी दुर्लभ परिस्थितियों में "नहीं" होता है।

मैं एक दोस्त के लिए कुछ कोड की समीक्षा कर रहा हूं और कहता हूं कि वह कोशिश-अंत में ब्लॉक के अंदर रिटर्न स्टेटमेंट का उपयोग कर रहा था। क्या अंत में खंड में कोड अभी भी आग लग रहा है भले ही बाकी प्रयास ब्लॉक नहीं है?

उदाहरण:

public bool someMethod()
{
  try
  {
    return true;
    throw new Exception("test"); // doesn't seem to get executed
  }
  finally
  {
    //code in question
  }
}

अंत में यदि आप System.exit (0) का उपयोग कर एप्लिकेशन से बाहर निकल रहे हैं तो दौड़ नहीं पाएंगे; जैसे की

try
{
    System.out.println("try");
    System.exit(0);
}
finally
{
   System.out.println("finally");
}

नतीजा सिर्फ होगा: कोशिश करें


आम तौर पर हाँ, आखिरकार भाग जाएगा।

निम्नलिखित तीन परिदृश्यों के लिए, अंत में हमेशा चलेंगे:

  1. कोई अपवाद नहीं होता है
  2. सिंक्रोनस अपवाद (सामान्य प्रोग्राम प्रवाह में होने वाले अपवाद)।
    इसमें सीएलएस अनुपालन अपवाद शामिल हैं जो System.Exception और गैर-सीएलएस अनुपालन अपवादों से प्राप्त होते हैं, जो सिस्टम से प्राप्त नहीं होते हैं। अपवाद। गैर-सीएलएस अनुपालन अपवाद स्वचालित रूप से RuntimeWrappedException द्वारा लिपटे हैं। सी # गैर-सीएलएस शिकायत अपवाद नहीं फेंक सकता है, लेकिन सी ++ जैसी भाषाएं कर सकती हैं। सी # एक ऐसी भाषा में लिखे गए कोड में कॉल कर सकता है जो गैर-सीएलएस अनुपालन अपवादों को फेंक सकता है।
  3. Asynchronous ThreadAbortException
    .NET 2.0 के रूप में, एक थ्रेडएबॉर्ट अपवाद अब अंततः चलने से रोक नहीं पाएगा। ThreadAbortException अब अंत में या बाद में फहराया गया है। आखिरकार हमेशा चलेंगे और थ्रेड निरस्त होने से बाधित नहीं होंगे, जब तक कि थ्रेड निरस्त होने से पहले वास्तव में प्रयास किया गया था।

निम्नलिखित परिदृश्य, आखिरकार नहीं चलेगा:

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

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

तो तथ्य यह है कि अंत में Exception पर नहीं चलता है, उपयोगकर्ता कोड पर कोई प्रभाव नहीं पड़ता है, क्योंकि प्रक्रिया वैसे भी समाप्त हो जाएगी। यदि आपके पास कुछ बढ़त का मामला है जहां आपको कुछ अप्रबंधित संसाधन को साफ़ करने की आवश्यकता है, तो एक सुरक्षित हैंडल या क्रिटिकलफिनलाइज़र ऑब्जेक्ट के बाहर, फिर निम्नानुसार सीईआर का उपयोग करें; लेकिन कृपया ध्यान दें, यह बुरा अभ्यास है - अप्रबंधित अवधारणा को एक प्रबंधित वर्ग (एसएस) और डिजाइन द्वारा उचित सेफहैंडल (एस) के लिए सारणीबद्ध किया जाना चाहिए।

जैसे,

// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{ 
    // This is *NOT* a CER
}
finally
{
    // This is a CER; guaranteed to run, if the try was entered, 
    // even if a Exception occurs.
}

आम तौर पर, हाँ। अंत में अनुभाग अपवाद या वापसी विवरण सहित जो कुछ भी होता है उसे निष्पादित करने की गारंटी देता है। इस नियम का अपवाद थ्रेड ( OutOfMemoryException , Exception ) पर एक असीमित अपवाद हो रहा है।

उन स्थितियों में एसिंक अपवाद और विश्वसनीय कोड के बारे में और जानने के लिए, बाधित निष्पादन क्षेत्रों के बारे में पढ़ें।


एमएसडीएन से उद्धरण

आखिरकार कोड निष्पादन के एक कथन ब्लॉक की गारंटी के लिए उपयोग किया जाता है, भले ही पिछले प्रयास ब्लॉक को बाहर किया गया हो


मुझे एहसास है कि मैं पार्टी के लिए देर हो चुकी हूं लेकिन परिदृश्य में (ओपी के उदाहरण से भिन्न) जहां वास्तव में एक अपवाद एमएसडीएन राज्यों को फेंक दिया जाता है ( https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx ): "अगर अपवाद पकड़ा नहीं जाता है, तो आखिरकार ब्लॉक का निष्पादन इस बात पर निर्भर करता है कि ऑपरेटिंग सिस्टम अपवाद को खोलने का विकल्प चुनता है या नहीं।"

आखिरकार ब्लॉक केवल निष्पादित करने की गारंटी है अगर कॉल स्टैक के आगे कुछ अन्य फ़ंक्शन (जैसे मुख्य) अपवाद को पकड़ लेता है। यह विवरण आमतौर पर एक समस्या नहीं है क्योंकि सभी रन टाइम वातावरण (सीएलआर और ओएस) सी # प्रोग्राम मुफ्त अधिकांश संसाधनों पर चलते हैं, जब प्रक्रिया समाप्त होती है (फ़ाइल हैंडल इत्यादि)। कुछ मामलों में यह महत्वपूर्ण हो सकता है हालांकि: डेटाबेस ऑपरेशन आधा चल रहा है जिसे आप resp प्रतिबद्ध करना चाहते हैं। तनाव कम; या कुछ रिमोट कनेक्शन जो ओएस द्वारा स्वचालित रूप से बंद नहीं हो सकते हैं और फिर सर्वर को अवरुद्ध कर सकते हैं।


यहां एक छोटा परीक्षण है:

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        Console.WriteLine("before");
        Console.WriteLine(test());
        Console.WriteLine("after");
    }

    static string test()
    {
        try
        {
            return "return";
        }
        finally
        {
            Console.WriteLine("finally");
        }
    }
}

परिणाम है:

before
finally
return
after

सरल उत्तर: हां।





try-catch