2010-11-16 17 views
6

ब्लॉक करें, मुझे कोशिश करने, पकड़ने और अंत में निष्पादन को रोकने के क्रम में बड़ा भ्रम हो रहा है।प्रयास पकड़ने के निष्पादन के आदेश और आखिरकार

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

+0

कृपया पूर्ण विराम उपयोग करना सीखना ('.') और प्रश्न चिह्न ('?') उचित रूप से। मैं आपके प्रश्न का कोई अर्थ नहीं बना सकता क्योंकि यह वर्तमान में खड़ा है। – BoltClock

उत्तर

6

यदि आपके पास (ध्यान दें: इस वैध सी #, एक वैध उदाहरण के लिए नीचे देखें नहीं है):

try { 
    // ... some code: A 
} catch(...) { 
    // ... exception code: B 
} finally { 
    // finally code: C 
} 

कोड एक क्रियान्वित किया जा रहा है। अगर सब ठीक हो जाए (यानी ए निष्पादित होने पर कोई अपवाद नहीं फेंक दिया जाता है), तो अंत में यह जा रहा है, इसलिए कोड सी को निष्पादित किया जा रहा है। एक अपवाद है, जबकि एक फेंक दिया जाता है, तो मार डाला जाता है, तो यह बी को तो अंत में सी

को एक उदाहरण के रूप जाना होगा और, यहाँ http://msdn.microsoft.com/en-us/library/dszsf989.aspx से एक वैध सी # कोड ब्लॉक है:

public class EHClass 
{ 
    void ReadFile(int index) 
    { 
     // To run this code, substitute a valid path from your local machine 
     string path = @"c:\users\public\test.txt"; 
     System.IO.StreamReader file = new System.IO.StreamReader(path); 
     char[] buffer = new char[10]; 
     try 
     { 
      file.ReadBlock(buffer, index, buffer.Length); 
     } 
     catch (System.IO.IOException e) 
     { 
      Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message); 
     } 
     finally 
     { 
      if (file != null) 
      { 
       file.Close(); 
      } 
     } 
     // Do something with buffer... 
    } 
} 

कारण उपयोग करने के लिए किसी कोड में कोई त्रुटि होने पर (उपरोक्त उदाहरण में ए) में विफल होने के लिए अपने प्रोग्राम को विफल करने के लिए प्रयास करें/पकड़ें/अंत में है। यदि कोई समस्या है, तो आप समस्या को पकड़ने के लिए catch भाग का उपयोग कर सकते हैं और कुछ उपयोगी कर सकते हैं, जैसे कि उपयोगकर्ता को सूचित करें, लॉग फ़ाइल में अपवाद लॉग करें, पुनः प्रयास करें या कुछ अलग कोशिश करें जो आपको लगता है कि आपने जो कोशिश की है उसके बजाय काम कर सकते हैं मौलिक रूप से।

finally यह सुनिश्चित करने के लिए उपयोग किया जाता है कि कुछ सफाई की जाती है। जैसे ए में आप एक फ़ाइल खोलने और इसे पढ़ने की कोशिश कर सकते हैं। यदि सफलता प्राप्त हो रही है, लेकिन पढ़ना विफल रहता है, तो आपके पास एक खुली फ़ाइल लटकती होगी। उस मामले में आप जो चाहते हैं उसे बंद करना है, जो आप finally ब्लॉक में करेंगे - यह ब्लॉक हमेशा फ़ाइल को बंद करने की गारंटी देता है, जो हमेशा निष्पादित हो जाता है।

अधिक जानकारी के लिए यहां एक नज़र डालें:

+0

महोदय, "उपयोगकर्ता परिभाषित स्थितियों" पर अपवादों का अर्थ क्या है? – NoviceToDotNet

+0

सुनिश्चित नहीं है कि मैं समझता हूं कि "उपयोगकर्ता परिभाषित स्थितियों" से आपका क्या मतलब है - यदि आपका मतलब उपयोगकर्ता परिभाषित अपवाद है, तो यहां देखें: http://msdn.microsoft.com/en-us/library/87cdya3t.aspx। उपयोगकर्ता परिभाषित अपवादों का उपयोग तब किया जाता है जब सिस्टम द्वारा परिभाषित अपवादों में से कोई भी आपको उस त्रुटि का उपयुक्त स्पष्टीकरण देता है जिसे आप सिग्नल करना चाहते हैं। –

+0

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

5

आपको लगभग कभी भी प्रयास/पकड़ का उपयोग नहीं करना चाहिए।

आपको केवल catch अपवादों को अवश्य ही सही करना चाहिए, और केवल तभी जब आप उन्हें उम्मीद कर रहे हों। अन्यथा, कॉलर अपवाद को संभाल लें - या नहीं।

यदि उपयोग किया जाता है, तो catch खंडों को पहले ही निष्पादित किया जाता है - उनमें से केवल एक ही।

फिर, finally "आखिरकार" निष्पादित किया गया है।


यह कई स्थानों पर बेहतर कहा गया है, लेकिन मैं कोशिश करूंगा। निम्नलिखित कोड:

try 
{ 
    // Do something here 
} 
catch (Exception ex) 
{ 
    MessageBox.Show("Friendly error message"); 
} 

अपवाद को ठीक नहीं करता है। यह अपवाद को छुपाता है ताकि समस्या कभी तय नहीं की जाएगी। उस कोड को पता नहीं है कि कौन सा अपवाद फेंक दिया गया था, क्योंकि यह उन सभी को पकड़ लेगा, और यह समस्या को ठीक करने के लिए कुछ भी नहीं करता है - यह सिर्फ उपयोगकर्ता को विनम्र कथा बताता है।

इस मामले के तथ्य यह है कि कोड के ऊपर निम्नलिखित के साथ प्रतिस्थापित किया जाना चाहिए है:

// Do something here 

इस तरह इस विधि के फोन करने वाले जानता है विशेष रूप से समस्याओं को ठीक करने के लिए कैसे, तो फोन करने वाले उन्हें ठीक कर सकते हैं । आपने कॉलर से उस विकल्प को नहीं हटाया होगा।

यदि कॉलर को समस्या को ठीक करने का तरीका नहीं पता है, तो कॉलर को अपवाद भी नहीं पकड़ना चाहिए।


उचित तरीके से अपवादों का उपयोग करने के लिए यहां एक उदाहरण (एमएसडीएन से) है। यह SmtpFailedRecipientsException Class के दस्तावेज़ में उदाहरण का एक संशोधित रूप है।

public static void RetryIfBusy(string server) 
{ 
    MailAddress from = new MailAddress("[email protected]"); 
    MailAddress to = new MailAddress("[email protected]"); 
    using (
     MailMessage message = new MailMessage(from, to) 
            { 
             Subject = "Using the SmtpClient class.", 
             Body = 
              @"Using this feature, you can send an e-mail message from an application very easily." 
            }) 
    { 
     message.CC.Add(new MailAddress("[email protected]")); 
     using (SmtpClient client = new SmtpClient(server) {Credentials = CredentialCache.DefaultNetworkCredentials}) 
     { 
      Console.WriteLine("Sending an e-mail message to {0} using the SMTP host {1}.", to.Address, client.Host); 
      try 
      { 
       client.Send(message); 
      } 
      catch (SmtpFailedRecipientsException ex) 
      { 
       foreach (var t in ex.InnerExceptions) 
       { 
        var status = t.StatusCode; 
        if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable) 
        { 
         Console.WriteLine("Delivery failed - retrying in 5 seconds."); 
         System.Threading.Thread.Sleep(5000); // Use better retry logic than this! 
         client.Send(message); 
        } 
        else 
        { 
         Console.WriteLine("Failed to deliver message to {0}", t.FailedRecipient); 
          // Do something better to log the exception 
        } 
       } 
      } 
      catch (SmtpException ex) 
      { 
       // Here, if you know what to do about particular SMTP status codes, 
       // you can look in ex.StatusCode to decide how to handle this exception 
       // Otherwise, in here, you at least know there was an email problem 
      } 
      // Note that no other, less specific exceptions are caught here, since we don't know 
      // what do do about them 
     } 
    } 
} 

ध्यान दें कि यह कोड कोड के एक छोटे टुकड़े को घेरने के लिए प्रयास/पकड़ का उपयोग करता है। उस कोशिश/पकड़ ब्लॉक के भीतर, यदि एक SmtpException या SmtpFailedRecipientsException फेंक दिया गया है, तो हम जानते हैं कि इसके बारे में क्या करना है। उदाहरण के लिए, हम IOException पकड़ना चाहते थे, हम नहीं जानते कि इसका क्या अर्थ है, या इसके बारे में क्या करना है। कोई अपवाद जो आपको वास्तव में नहीं जानता है कि कैसे सही किया जाए, पकड़ा नहीं जाना चाहिए, सिवाय इसके कि अपवाद में जानकारी जोड़ने, इसे लॉग इन करने और फिर से निकालने के अलावा।

+0

अब मैं और अधिक उलझन में हूं, महोदय, मुझे कोशिश पकड़ने का प्रयास क्यों नहीं करना चाहिए? और यदि अग्रिम में मुझे पता है कि अपवाद कहाँ आएगा तो मैं इसे पहले से ही सही कर दूंगा। इसके अलावा आपका बयान क्या है "कॉलर को अपवाद को संभालने दें - या नहीं।" – NoviceToDotNet

+0

यदि आप समझ नहीं पाते कि आप क्या कर रहे हैं, तो सुनकर देखें। इसका इस्तेमाल न करें। बस अपवाद छोड़ दें। यदि आपका कोड एक अपवाद फेंक रहा है जो इसे नहीं करना चाहिए, तो अपने कोड को ठीक करें। अधिकांश डेवलपर्स के लिए अपवादों को पकड़ने के बहुत कम कारण हैं। –

4

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

यदि कोई अपवाद नहीं होता है तो try ब्लॉक में कोड अपेक्षित है। यदि finally ब्लॉक है तो वह अगले निष्पादित होगा।

यदि कोई अपवाद होता है तो निष्पादन पहले मिलान catch ब्लॉक की शुरुआत में कूदता है। एक बार जब कोड पूरा हो जाता है तो अंत में ब्लॉक (यदि यह मौजूद है) निष्पादित किया जाता है। निष्पादन try ब्लॉक पर वापस नहीं आता है।

1

यहाँ एक उदाहरण है:

try 
{ 
    someFunctionThatWorks(); 

    functionThatThrowsAnException(); // As soon as this function throws an exception we are taken to the catch block 

    anotherFunction(); // <-- This line will never get executed 
} 
catch(Exception e) 
{ 
    // Here you can handle the exception, if you don't know how to handle it you should not be catching it 
    // After this you will not be taken back to the try block, you will go right to the finally block 
} 
finally 
{ 
    // Code here is always executed at the very end, regardless of whether an exception was thrown or not 
} 
+0

और महोदय, अगर आखिर में कुछ अपवाद फेंक दिया तो क्या होगा? – NoviceToDotNet

+0

यदि आखिरकार ब्लॉक में एक और अपवाद फेंक दिया गया है तो आप इसे किसी अन्य प्रयास को घोंसले से पकड़ सकते हैं ... अंत में, अन्यथा यह किसी अन्य अनचाहे अपवाद के रूप में कार्य करेगा। इसे देखें http://stackoverflow.com/questions/481446/throws-exception-in-finally-blocks – tbridge

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