2011-05-27 6 views
5

मैं उदाहरण के रूप में SO से कोड का एक टुकड़ा कॉपी करता हूं। Subroutine में एक त्रुटि हैंडलर होता है। क्या किसी को सभी सब्सक्रिप्शन के लिए त्रुटि हैंडलर बनाना चाहिए?क्या हमें प्रत्येक सबराउटिन के लिए त्रुटि हैंडलर बनाने की आवश्यकता है?

Public Sub SubA() 
    On Error Goto ProcError 

    Connection.Open 
    Open File for Writing 
    SomePreciousResource.GrabIt 

ProcExit: 
    Connection.Close 
    Connection = Nothing 
    Close File 
    SomePreciousResource.Release 

    Exit Sub 

ProcError: 
    MsgBox Err.Description 
    Resume ProcExit 
End Sub 

और वैसे, कैसे एक सबरूटीन के अंदर नियंत्रण के प्रवाह जब कोड निष्पादक एक Exit Sub, End Sub और Resume मुठभेड़ करता है? और जब यह निष्पादन के दौरान ProcError: जैसे किसी लेबल से मुकाबला करता है, तो क्या यह इसे निष्पादित करता है, या क्या इसे छोड़ देता है?

उत्तर

2

बाहर निकलें उप immediatly जावा में वापसी की तरह सबरूटीन बाहर निकल जाएगा

End Sub जावा

में की तरह उप दिनचर्या ब्लॉक के अंत के लिए सिर्फ मार्कर} है एक लेबल बस कोड में एक निशान है एक कूद गंतव्य को परिभाषित करने के लिए उपयोग किया जाता है। यदि आप लेबल पर नहीं गए थे लेकिन वहां पहुंचे तो "नियमित रूप से" लेबल को अनदेखा कर दिया जाएगा, लेकिन लेबल के बाद कोड निष्पादित किया जाएगा जैसे कोई लेबल नहीं था, आपके उदाहरण में कोड को सभी तरह से निष्पादित किया जाएगा जब तक कोई त्रुटि नहीं होती तब तक उप-कथन से बाहर निकलें। एक occures यह ProcError

पर चला जाएगा

फिर से शुरू इस मामले में निष्पादित करेंगे तो ProcExit देखना अधिक here

+0

आपने कहा कि लेबल ब्लॉक को अनदेखा कर दिया जाएगा, लेकिन यह ब्लॉक को कैसे पहचानता है और शेष कोड के साथ अलग करता है? – lamwaiman1988

+1

@ gunbuster363: मुझे लगता है कि @ cmmi का कथन सही प्रकार का है, हालांकि स्पष्ट रूप से व्यक्त नहीं किया गया है। "लेबल को अनदेखा किया जाएगा" का क्या अर्थ है: निष्पादित होने पर लेबल स्वयं कुछ भी नहीं करता है। हालांकि, लेबल के बाद कोड (जिसे आप "लेबल ब्लॉक" कहते हैं) निश्चित रूप से अनदेखा नहीं किया जाएगा और निष्पादित किया जाएगा। –

+0

मुझे लगता है कि मुझे अब मिल गया है। – lamwaiman1988

9

संक्षिप्त उत्तर है: नहीं, आप न केवल नहीं जरूरत प्रत्येक प्रक्रिया में कोई त्रुटि हैंडलर के लिए करते हैं, लेकिन वास्तव में आप आमतौर पर प्रत्येक प्रक्रिया में एक त्रुटि हैंडलर नहीं चाहते हैं।

आप त्रुटि प्रबंधन करना चाहते हैं जहां इसे करने के लिए सबसे अधिक समझदारी होती है। अक्सर, आप केवल उच्चतम स्तर की प्रक्रिया में एक त्रुटि हैंडलर चाहते हैं, यानी वह सभी जो दूसरों को बुलाता है; निचले स्तर की प्रक्रियाओं को ऊपर की ओर समस्या को लात मारना चाहिए और उच्च स्तर की प्रक्रिया में त्रुटियों को "बबल अप" करना चाहिए। कभी-कभी आप निम्न-स्तरीय प्रक्रियाओं में कुछ त्रुटि प्रबंधन करना चाहते हैं।

अधिक के लिए, मैं @jtolle द्वारा इन दो उत्कृष्ट जवाब का उल्लेख:

इसके अलावा, एक इंटरनेट खोज का पता चलता है पर एक पूरा साहित्य है कि वहाँ त्रुटि प्रबंधन के बारे में वेब। मेरी राय में कुछ गलत है! लेकिन अगर यह पहले दो अनुच्छेदों में मैंने जो लिखा है, उसके लिए चिपक जाता है, तो यह विचार करने लायक है।

Exit Sub और End Sub काफी सहज ज्ञान युक्त हैं: पूर्व वर्तमान उप निष्पादन को रोकता है और इसे नियंत्रित करने वाली प्रक्रिया पर नियंत्रण लौटाता है (या प्रक्रिया को पूरी तरह से रोकता है अगर प्रक्रिया को किसी अन्य प्रक्रिया द्वारा नहीं कहा जाता है)। उत्तरार्द्ध संकलक के लिए सिर्फ एक संकेत है कि यह जहां इस विशेष सब सिरों के लिए कोड - और यदि निष्पादित किया गया है, End SubExit Sub जैसा व्यवहार करता है।

Resume त्रुटि-हैंडलिंग दिनचर्या समाप्त होने के बाद, आगे क्या होना चाहिए, यह निर्दिष्ट करता है। सादा Resume उसी कथन पर लौटता है जो त्रुटि उत्पन्न करता है और इसे फिर से निष्पादित करने का प्रयास करता है। Resume Next उस कथन को छोड़ देता है जो त्रुटि उत्पन्न करता है, और इसके बाद तुरंत इसके बाद कथन पर जाता है। Resume mylabelmylabel: लेबल पर जाता है।

एक लेबल जैसे अपने ProcError: निष्पादन के दौरान encoutered है, तो कुछ खास नहीं होता है, और निष्पादन अगले स्टेटमेंट पर जाता है लेबल के बाद है। बेशक आपके उदाहरण में, ProcError: सीधे निष्पादित नहीं होगा (यानी जब तक कोई त्रुटि नहीं उठाई जाती है) क्योंकि इससे पहले Exit Sub है।


वैसे, ProcExit: ब्लॉक शायद एक On Error Goto 0 (त्रुटि के रूप में @Phydaux से कहा, या वैकल्पिक रूप (यानी सब कुछ बंद करने और चाहे कोई भी त्रुटि बाहर निकलने पर रखने के लिए), एक On Error Resume Next साथ शुरू करना चाहिए, बंद करो निष्पादन), अन्यथा अगर वहां कोई त्रुटि किसी त्रुटि को ट्रिगर करती है, तो आप त्रुटि हैंडलर और ProcExit: कोड के बीच एक अनंत पिंग-पोंग लूप में जा सकते हैं।

ProcExit: 
    On Error Resume Next ' or, alternatively, On Error Goto 0 
    Connection.Close 
    Connection = Nothing 
    Close File 
    SomePreciousResource.Release 
Exit Sub 
+0

@ जीन: त्रुटि हैंडलर लेबल के बाद ''त्रुटि फिर से शुरू करें' के लिए +1। मैंने जो किया है उस पर पुनर्विचार किया। लेकिन, अगर मैं त्रुटि के बाद लाइन को निष्पादित करने के बाद लाइन चाहता हूं तो क्या होगा? क्या उस मामले में 'फिर से शुरू करें' का उपयोग करना ठीक है? आशा है कि आप जो कहने की कोशिश कर रहे हैं वह प्राप्त करें (अंग्रेजी मेरी मां भाषा नहीं है)। – Oneide

+1

ProcExit के लिए: अनुभाग 'त्रुटि पर GoTo 0' भी उपयुक्त हो सकता है। लेकिन आप निश्चित रूप से एक या दूसरे को चाहते हैं या आप अनंत लूप के जोखिम में हैं। –

+0

@Oneide: आपका मतलब है, त्रुटि प्रबंधन करना है, और फिर त्रुटि के कारण बयान के बाद लाइन निष्पादित करने के लिए आगे बढ़ें? हां, उस स्थिति में, 'अगला फिर से शुरू करें' आपके त्रुटि हैंडलर का अंतिम विवरण होना चाहिए। ईमानदार होने के लिए, हालांकि, मुझे ऐसा करने का कोई अच्छा कारण कभी नहीं मिला है। –