2011-11-22 8 views
5

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

मेरे ऐप (और कोड की मात्रा) का आकार आधा में कटौती करने की आवश्यकता नहीं है। लेकिन जैसे ही मैं जा रहा था, मैंने अपने आवेदन में कुछ और देखा जो दोहराया गया प्रतीत होता था और ऐसा लगता था कि इसे बेहतर किया जा सकता है।

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

तो यहाँ का एक टुकड़ा की तरह है कि मैं क्या लिखने की आवश्यकता:

try 
    { 
    ItemManager.SaveTextPost(myPostItem); 
    } 
    // Majority of the time there is more than one catch! 
    catch 
    { 
    //^^^Not to mention that I have to handle multiple types of exceptions 
    //in order to log them correctly(more catches..ugh!) 
    MessageBox.Show("There was an error saving the post."); 
    //Perform logging here as well 
    } 

मैं अब तक क्या यह निष्कर्ष निकाला है से है:

  • मुझे इस के लिए overkill 50 से अधिक इस लिखने के लिए हो रही है मेरे ऐप के लिए समय। लगता है जैसे मुझे हेल्पर क्लास में शामिल होना चाहिए और में कैच का पूरा सेट शामिल है।
  • लेकिन मैं परिणाम कैसे जान सकता हूं? मैं शायद स्ट्रिंग लौटने की सोच रहा था जिसमें त्रुटि/सफलता संदेश शामिल है।
  • वास्तव में इस तरह के तरीकों के लिए इसे उस विधि की आवश्यकता नहीं है जिसके द्वारा सहायक विधि को इसे कोशिश/पकड़ ब्लॉक में संलग्न करने के लिए कहा जा रहा है।

क्या यह दृष्टिकोण सही है? क्या ऐसा करने का कोई और तरीका है? क्या मुझे कॉलिंग विधि में कोशिश/पकड़ का उपयोग करना चाहिए? इस तरह से मेरा पहला शॉट इस तरह से मैं वास्तव में यह सुनना चाहूंगा कि इस परिदृश्य को संभालने वाले अन्य लोगों ने क्या कहना है।

+0

ऐसा ही एक सवाल हाल ही में पूछा गया था: http://stackoverflow.com/questions/8156530/exception-handling-in-method-definition-or-call/8156574#8156574 – Tudor

उत्तर

1

मुझे लगता है कि जिस विधि को आप बुला रहे हैं उसमें प्रयास/पकड़ डालना बिल्कुल ठीक है। आप विभिन्न तरीकों से कॉलिंग कोड में त्रुटि/सफलता कोड वापस कर सकते हैं। .NET और C# अच्छी तरह से संभालते हैं, इसलिए आपके पास ItemManager.SaveTextPost(myPostItem, out errorCode); हो सकता है जहां त्रुटि कोड एक गणना मूल्य होगा जो आपको बताएगा कि क्या कोई समस्या हुई है। यह आसान हो सकता है क्योंकि विधि सफल होने पर एक बूल सत्य वापस कर सकती है, अगर अन्यथा गलत हो। ऐसे कई तरीके हैं जिन्हें आप उस मुद्दे को संभाल सकते हैं, लेकिन जहां तक ​​मैं चिंतित हूं कि विधि में प्रयास/पकड़ डालना चीजों को करने का बेहतर तरीका है।

+0

एक enumerated मूल्य वापस भेजने के लिए +1। मुझे लगता है कि यह एक अच्छा विचार है। किसी भी तरह से मुझे पता था कि एक स्ट्रिंग हाहा भेजने से बेहतर तरीका था। – loyalpenguin

+0

मैं 'SaveTextPost (myPostItem, आउट त्रुटि कोड)' तरीके से नहीं जाऊंगा। यह कोड का उपयोग करने वाले लोगों के लिए भ्रमित हो सकता है और यह त्रुटि मानों के अंक के साथ बनाए रखने के लिए बहुत अधिक दर्दनाक है। इसके अलावा, त्रुटियों का इलाज करने के लिए डिज़ाइन अपवाद नहीं हैं? एक बुलियन लौटें ठीक है, हालांकि, यदि आपके लिए 'सत्य' और 'झूठा' पर्याप्त है। – Otiel

+0

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

1

AOPPostSharp जैसे पुस्तकालयों को इस तरह क्रॉस-कटिंग चिंताओं को संभालने के लिए डिज़ाइन किया गया है।

यदि ये सभी सहायक तरीके एक ही बॉयलरप्लेट को नियोजित करते हैं, तो पकड़ने की कोशिश करें -> कई प्रकार के अपवादों को संभाल लें, फिर आप एक पहलू लिख सकते हैं जो ऐसा करता है, और उपयुक्त विशेषता के साथ सभी प्रासंगिक तरीकों को सजाने के लिए।

1

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

1

आप if ब्लॉक के साथ जाँच अगर हर तर्क सही है के द्वारा अपने सहायक तरीकों में अपवाद फेंक देना चाहिए, हर फ़ाइल पहुंचा जा सकता है ... तो यदि आवश्यक हो, अपने सहायक के तरीकों में कुछ try catch ब्लॉकों को लागू करने और जब पकड़ने अपवाद फेंक देते हैं।

अंत में

, एक try catch ब्लॉक द्वारा इन सहायक तरीकों संलग्न है, लेकिन इस समय, वास्तव में पकड़ अपवाद:

try 
{ 
    ItemManager.SaveTextPost(myPostItem); 
    // SaveTextPost can throw some exceptions (that you know) 
} 
catch (Exception e) 
{ 
    // You know the exceptions that SaveTextPost can return, so threat them 
    // correctly 
    if (e is FileNotFoundException) 
     MessageBox.Show("The file was not found when saving the post."); 
    else if (e is ArgumentNullException) 
     MessageBox.Show("The post can't be null to be saved."); 
    else 
     MessageBox.Show("There was an error saving the post."); 
} 

अंत में, आप त्रुटि का इलाज और एक दिखाने की जरूरत है उपयोगकर्ता को त्रुटि संदेश। आप केवल यह तय कर सकते हैं कि MessageBox.Show सहायक विधि में या सहायक विधि को कॉल करने वाले वर्ग में लागू किया जाना चाहिए या नहीं।
व्यक्तिगत रूप से, मुझे लगता है कि किसी भी डेवलपर द्वारा सहायक विधियों का उपयोग करने के लिए नियत किया जाता है जो आपके कोड को चलाएंगे, इसलिए आपको उसे यह तय करना चाहिए कि वह त्रुटि के साथ क्या करना चाहता है। इसका मतलब है सहायक विधि में अपवाद फेंकना।

+0

हां, लेकिन विधि/कॉल ब्लॉक में विधि को संलग्न करने का उद्देश्य होगा यदि आपकी कॉलिंग पहले से ही संभव अपवादों को संभालती है। ईमानदार होने के लिए मैं उससे दूर जाना चाहता हूं। मुझे लगता है कि 99.9% मौका है कि यह कैसे असफल हो सकता है ... – loyalpenguin

+0

+1 मुझे नहीं पता था कि आप इस तरह के अपवाद के प्रकार को निर्धारित कर सकते हैं। कुछ सीखा मैं निश्चित रूप से इस बात से भी सहमत हूं कि जिस तरह से डेवलपर संदेश को संवाद करने का विकल्प चुनता है (कभी-कभी कभी नहीं) उन्हें छोड़ दिया जाना चाहिए। – loyalpenguin

+2

उस प्रकार की तुलना आपके काम करने की कोशिश के लिए काम नहीं करेगी .. अगर कुछ (ई फ़ाइल फ़ाइल नहीं है) {} – iamkrillin

0

मेरा व्यक्तिगत अपवाद हैंडलिंग पर लेना है .. try {} catch {} जोड़ें जहां यह समझ में आता है।

उदाहरण के लिए हमेशा "अविश्वसनीय" कोड, यानी मॉड्यूल या प्लगइन्स को कॉल करते समय प्रयास करने का प्रयास करें। अन्यथा यदि आप अपवाद पकड़ने जा रहे हैं तो सुनिश्चित करें कि आप इसके साथ सार्थक कुछ कर सकते हैं। यदि नहीं, तो अपवाद को उस बिंदु तक बुलबुला करने दें जहां आप कर सकते हैं।

डेवलपर्स को अपवाद पकड़ा गया है और एक बूल लौटने की कोशिश करने से कुछ चीजें बदतर हैं। बस कहें '

1

कोशिश/पकड़ एक अच्छा समाधान है। एक सुझाव यह है, मैं इस का उपयोग करने के लिए त्रुटियों के प्रवाह स्टेम चाहते: अपवाद को पकड़ने: कोशिश { } पकड़ (अपवाद पूर्व) { ShowExceptionError (पूर्व); } तो मैं बस सभी अपवादों को एक ही विधि में फेंक दूंगा, और विधि को प्रत्येक को संभालने दें।

इस तरह का प्रकार:

private void ShowExceptionError(ex) 
{ 
    string errorMessage = "Type of error:" + ex.GetType().ToString(); 
    string stackTrace = ex.StackTrace(); 
    MessageBox.Show(errorMessage + "\n\n" + stackTrace); 
} 
1

इन तरीकों के सभी महान विकल्प हैं। एक चीज जिसे आप नहीं करना चाहते हैं, प्रवाह नियंत्रण के लिए {} पकड़ {} का प्रयास करना है। इसका मतलब है कि इस तरह कुछ (फिर से बचें)

Void SomeMethod() 
{ 
    try 
    { 
     while(somecondition) 
     { 
      try 
      { 
      } 
      catch (Exception ex) 
      { 

      } 
      } 
    } 
    catch (Exception ex) 
    { 
      ..... 
    } 

इसके बजाय आप रक्षात्मक रूप से कोड करना चाहते हैं।