2010-02-12 9 views
9

मुझे obj = null या obj.member = null जैसी त्रुटि स्थितियों के जवाब में कई सी # एप्लिकेशन क्रैश मिले हैं। बहुत समय, 3rdPartyApp के इंटरफ़ेस से obj। और दोनों तृतीयPartyApp और MyCsApp दोनों एक साथ दुर्घटनाग्रस्त हो गए।मैं सभी अपवाद कैसे निगल सकता हूं और अपने एप्लिकेशन को क्रैश होने से कैसे बचा सकता हूं?

मैं सभी संभावित क्षेत्रों में अपवाद हैंडलिंग कैसे जोड़ सकता हूं ताकि मेरा आवेदन इन विनाशकारी परिस्थितियों में जीवित रहे? सभी स्थानों पर प्रयास करने और स्थिति से ठीक होने के लिए एक चुनौती है।

मैं इसे यथार्थवादी, विश्वसनीय और बुलेट प्रूफ के तरीके में कैसे पूरा कर सकता हूं?

[अद्यतन: उद्योग स्वचालन नियंत्रण]

संरचना:

जीयूआई (asp.net, C++) - RuntimeApp (C++) - MyCsApp (सीएस) - 3rdPartyApp (सी)

सामान्य प्रक्रिया :

  1. HostApp - MyCsApp
  2. ऑपरेटर - - (ईथरनेट Cabele के माध्यम से कनेक्ट करें) जीयूआई - आरयू ntimeApp - MyCsApp

असामान्य स्थिति:

  1. कुछ गैर मानक संचालन प्रक्रिया;
  2. कुछ हार्डवेयर समस्या आई;
  3. आदि

मैं बेहतर सब abnormall की स्थिति को संभाल चाहते हैं। और सबसे महत्वपूर्ण बात यह है कि मुझे लगता है कि परिस्थितियों से कैसे ठीक किया जाए।

+16

इसके बजाए बग को ठीक करने के बारे में कैसे? – Aaronaught

+0

@Aaronaught, हम पहले से ही कुछ स्थानों को सुरक्षित कर चुके हैं, इसका मतलब है कि हम असामान्य परिचालनों के तहत शर्श को खुश करने के बाद ही इसे ठीक कर सकते हैं। MyCsApp तृतीयPartyApp पर आधारित एक बहु-थ्रेड एप्लिकेशन। हमें कई प्रकार के लॉग (HostApp लॉग, रनटाइम लॉग, MyCsApp लॉग और तृतीयPartyApp लॉग) को पढ़ना होगा और इस मुद्दे को डुप्लिकेट करने के लिए अपना सर्वश्रेष्ठ प्रयास करना होगा। फिर हम इसे ठीक कर सकते हैं। –

+8

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

उत्तर

2

यह पहली बार बीमारी का इलाज करने के लिए, क्यों यह दुर्घटना पैदा पता लगाना मतलब होता है, यकीन है कि कोड obj = null या इसी तरह की वजह से क्रैश हो रहा है - अपवाद हैंडलिंग का उपयोग करने और सभी अपवादों को निगलने बस समस्या मास्किंग है .... ऐसा इसलिए है इसके लिए क्या उपयोग नहीं किया जाता है!ऐसा लगता है कि क्रैश को ट्रिगर करने वाली बहुत सारी कोड-गंध है - क्रैशिंग से आपके एप्लिकेशन को सुरक्षित करने का यह सही तरीका नहीं है और केवल चीजों को और खराब कर रहा है ...

ठीक है, आप जॉन सॉंडर्स का अनुसरण कर सकते हैं और ऐसा करने के लिए pm100 के सुझाव ... लेकिन मूल कारण क्या है यह देखने के लिए इसे संभाल लें, दिन के अंत में इसे 'जादू चांदी बुलेट' के रूप में न मानें, कोड जो तीसरे पक्ष के आवेदन के साथ बातचीत कर रहा है अच्छी तरह से डिबग किए जाने की जरूरत है ...

उदाहरण के लिए

 
object foo = null; 
bar baz; 

// .... 
// foo is now set by thirdparty app 

if (foo != null && foo is bar) baz = (bar)foo as bar; 

if (baz != null){ 

    // Continue on, baz is a legitimate instance of type 'bar' 

}else{ 

    // Handle it gracefully or throw a *user defined exception* 

} 

इसकी जांच करने का '' के रूप में प्रयोग किया जाता है सूचना यदि 'foo' 'बार' उदाहरण के लिए सही प्रकार का है - अब इस के साथ तुलना करें, कि एक विशिष्ट कोड गंध

 
object foo = null; 
bar baz; 

// foo is now set by thirdparty app - ARE YOU REALLY SURE ITS NON-NULL? 
// IS IT REALLY OF TYPE 'BAR'? 

baz = foo; // CRASH! BANG! WALLOP! KERRUNCH! 

आशा इस मदद करता है, सादर, टॉम है ...।

+0

@ tommieb75 और Aaronaught। मैं आपकी कंपनी आवेदन समाधान के रूप में आपका जवाब स्वीकार करना चाहता हूं। ** मूल कारण खोजने और इसे ठीक करने का प्रयास करें **। @सब। मैं आपके उत्तरों के आधार पर और अधिक अध्ययन और अभ्यास करना चाहता हूं। यदि संभव हो, तो मैं आपके समाधान के साथ ** उप मॉड्यूल स्तर ** क्रैश हैंडल जोड़ने की कोशिश करूंगा। बहुत बहुत धन्यवाद। –

4

आप निश्चित रूप से कोशिश पकड़ नहीं जोड़ना चाहिए हर जगह

तुम सिर्फ सभी अपवादों के एक शीर्ष स्तर पकड़ की जरूरत है। यदि यह एक जीयूआई ऐप है तो बस 'समर्थन करने के लिए रिपोर्ट करें' कहकर एक बटन के साथ एक अच्छा संवाद प्रदर्शित करें (यह स्क्रीन या फ़ाइल में एक स्टैक ट्रेस स्नैपशॉट लिख सकता है)

यदि आप भाग्यशाली हैं तो ऐप कर सकता है जारी रखने के लिए (भाग्यशाली जब से तुम जानते हुए भी यदि आप वास्तव में बुरी तरह से फंस रहे हैं का कोई तरीका नहीं)

ध्यान दें कि आप भी इस

 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
     Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 

कर सकते हैं लेकिन यह does not यह crshing रोक, यह सिर्फ आप विफलता पर कब्जा करने देता है

19

आप नहीं करते हर जगह हर अपवाद को पकड़ना चाहता है।

आप अपने आवेदन की निचली परतों के "लीक आउट" से अपवादों को रोकना चाहते हैं, जहां तक ​​वे एप्लिकेशन को मार सकते हैं या इसे दूषित कर सकते हैं।

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

ComplexBuilder cb = new ComplexBuilder(); 
try 
{ 
    cb.AddOperation(...); // Once building starts, 
    cb.AddOperation(...); // it's not safe to use cb 
    cb.AddOperation(...); 
} 
catch (SpecificException ex) 
{ 
    cb.Cleanup();   // until it's cleaned up 
} 

// Now safe to access cb, whether or not an exception was thrown 

मैं हाल ही में एक ऐसी ही दृष्टिकोण के साथ एक आवेदन पत्र में फंस गयी। इस एप्लिकेशन का टुकड़ा था जिसे "महत्वपूर्ण" माना जाता था। जब वह "महत्वपूर्ण" बात हुई, तो ऐसी कुछ चीजें थीं जो होने वाली थीं, लेकिन जिन्हें "महत्वपूर्ण नहीं" माना जाता था। विचार यह था कि यदि "महत्वपूर्ण नहीं" भाग में अपवाद था, तो "महत्वपूर्ण" भाग जारी रखने के लिए आवश्यक था।

क्या हुआ यह है कि कुछ कारणों से संसाधन पढ़ने का प्रयास विफल रहा। यह स्ट्रिंग संसाधन के बजाय शून्य वापस लौटा। इसने String.Format कॉल में ArgumentNullException का कारण बना दिया। इससे अपवाद को कोड द्वारा पकड़ा गया जो अभी जारी रहा।

लेकिन पहले अपवाद और अंतिम के बीच, एक ऑब्जेक्ट आवंटित किया जाना था, और ऑब्जेक्ट का संदर्भ सेट करना था। लेकिन अपवाद के कारण, संदर्भ स्थापित करना कभी नहीं हुआ। नतीजा यह था कि मैंने NullReferenceException, चार स्टैक स्तर ऊपर और दो .csproj फ़ाइलों को वास्तविक समस्या से दूर देखा।

तो जब आप अपवादों को पकड़ने के बारे में बात करते हैं तो आपका प्रोग्राम जारी रह सकता है, आपको यह ध्यान रखना होगा कि इन सभी अपवादों को पकड़कर आपके कार्यक्रम का नियंत्रण प्रवाह काफी बदल गया है। वास्तव में, इसे इतना बदला जा सकता है कि अब आप यह निर्धारित नहीं कर सकते कि आपके प्रोग्राम को निष्पादित करना जारी रखना सुरक्षित है या नहीं।

+2

डिंग, डिंग, डिंग। हमें विजेता मिल गया। – mmcdole

0

ऐसे अपवादों से बचने के लिए एक तकनीक the null object pattern का उपयोग करना है।

बजाय होने Account account = null; आप Account account = Account.SpecialNullAccount; करना होगा और अपने खाते कक्षा में आप एक स्थिर Account वस्तु के रूप में SpecialNullAccount परिभाषित करेगा की

। अब यदि आप कुछ अपरिहार्य कोड (जैसे, लॉगिंग कोड कहें) में account.Name का उपयोग करने का प्रयास करते हैं, तो आपको अपवाद नहीं मिलता है, इसके बजाय आपको स्थिर शून्य ऑब्जेक्ट उदाहरण पर परिभाषित "कोई नाम" कहने की आवश्यकता होती है।

बेशक यह महत्वपूर्ण है कि ऐसी वस्तु किसी भी महत्वपूर्ण मामले में अपवादों को फेंक दें जैसे कि PayInvoice() या objectContext.SaveChanges() तो यह सुनिश्चित करने के लिए कदम उठाएं।

+1

@Hightechrider: हाँ, शून्य ऑब्जेक्ट पैटर्न अपवादों को रोकता है, लेकिन यह प्रोग्राम को और अधिक सही नहीं बनाता है। अपवाद होना, एप्लिकेशन को सुरक्षित करना बेहतर होगा, फिर समस्या को ठीक करें। –

+0

@ जॉन सॉंडर्स। असहमत है कि शून्य मूल्य पैटर्न आपके कोड में सुधार नहीं करता है। शून्य मान पैटर्न व्यर्थ अपवादों को रोकता है जो वास्तव में आवश्यक नहीं थे (उदाहरण के लिए लॉग (खाता नाम) कहीं नहीं है क्योंकि आप अपवाद चाहते हैं क्योंकि उपयोगकर्ता लॉग इन नहीं है) और यह आपके कोड के बारे में अधिक बताता है क्योंकि यह भूलने के बीच अंतर करता है एक चर प्रारंभ करने में और एक मूल्य है कि जानबूझ कर अभी तक सेट नहीं होने:। जब PayInvoice() विफल रहता है तो आप तुरंत देख सकते हैं कि ऐसा इसलिए है क्योंकि खाता मान सेट कभी नहीं किया गया था या क्योंकि उपयोगकर्ता के लॉग इन नहीं किया गया था OO में –

+0

अशक्त वस्तु पैटर्न बहुत है डेटाबेस में 'NULL' मानों के समान - यह कुछ समस्याएं हल करता है, लेकिन इसके साथ नए लोगों का पहाड़ लाता है। यह "असफल तेजी से" रोकता है, जिससे कार्यक्रम लंबे समय तक गलत तरीके से चलने की अनुमति देता है और बाद में रहस्यमय तरीके से विफल हो जाता है। इस परिदृश्य में शुद्धता सुनिश्चित करने में * क्या * मदद करेगा, जैसे कि स्पीक # द्वारा कार्यान्वित किए गए, लेकिन उस तरह के एक्सटेंशन को पेश करने का समय तब होता है जब कोड स्थिर होता है, हर जगह दुर्घटनाग्रस्त नहीं होता है। – Aaronaught

0

AppDomain.UnHandledException और/या AppDomain.ThreadException ऐसी घटनाएं हैं जिन्हें आप अनचाहे अपवादों को पकड़ने के लिए सदस्यता ले सकते हैं। मुझे नहीं लगता कि आप इसे निष्पादन जारी रखने के लिए इसका उपयोग कर सकते हैं जहां यह छोड़ा गया था (और यह शायद वैसे भी एक अच्छा विचार नहीं है)। वे त्रुटि संदेश निगल सकते हैं या इसे लॉग कर सकते हैं, आदि

चाहे यह करने के लिए एक अच्छा विचार है आप पर निर्भर है!

+1

इस सलाह के लिए एक चेतावनी यह है कि अगर अपवाद खराब/अप्राप्य स्थिति में होने के कारण हुआ, तो यह वास्तव में ऐप को दुर्व्यवहार करना जारी रखेगा, और उपयोगकर्ता को पूरी तरह से निराश करेगा। निश्चित रूप से क्रैश होने वाले ऐप से निपटने में निराशा होती है, हालांकि यह एक ऐसे ऐप से निपटने में अधिक निराशाजनक है जो अत्यधिक गलत व्यवहार कर रहा है। –

0

यदि यह एक Winforms आवेदन की तरह निम्न इवेंट के लिए के लिए ईवेंट हैंडलर्स जोड़ने के मुख्य विधि में है इस

Application.ThreadException += Application_ThreadException; 
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 

फिर आप एक messagebox या अन्य सूचना दिखा सकते हैं exeception आदि Loog और दुर्घटनाग्रस्त बिना काम जारी रखने के एप्लिकेशन।

+0

इस सलाह के लिए एक चेतावनी यह है कि अगर अपवाद खराब/अप्राप्य स्थिति में होने के कारण हुआ, तो यह वास्तव में ऐप को दुर्व्यवहार करना जारी रखेगा, और उपयोगकर्ता को पूरी तरह से निराश करेगा। निश्चित रूप से क्रैश होने वाले ऐप से निपटने में निराशा होती है, हालांकि यह एक ऐसे ऐप से निपटने में अधिक निराशाजनक है जो अत्यधिक गलत व्यवहार कर रहा है। –

+0

जेसन के साथ सहमत हैं। मैं एक LOB ऐप का वर्णन कर रहा था जिसमें व्यक्तिगत खराब डेटा के कारण त्रुटियां हैं और सामान्य रूप से नहीं। तो आप अपवाद को पकड़ने के बाद खुशी से जारी रख सकते हैं। आपके द्वारा काम किए जाने वाले डेटा का एक और सेट कोई समस्या नहीं हो सकता है। – softveda

+0

मैं यह नहीं कहूंगा कि आप "खुशी से" जारी रख सकते हैं। एक * न्यूनतम न्यूनतम * इन त्रुटियों को पूरी तरह से लॉग, जांच, ट्रैक, एक साधु और संगठित फैशन में हल करने की आवश्यकता है। बस फ़ाइल को छोड़ना या क्रिप्टिक डीबग संदेश आउटपुट करने से * एप्लिकेशन * चलने की अनुमति मिल सकती है लेकिन * व्यवसाय * बहुत तेज हो जाएगी। – Aaronaught

7

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

जब आप इस उच्च स्तरीय पकड़ तक पहुंचते हैं-जो आप प्रदान करने जा रहे हैं, तो आपके पास आपके ऐप को क्रैश होने से रोका नहीं है। आप बस पर निर्णय ले रहे हैं कि उस बिंदु पर क्रैश के बारे में क्या करना है। आप मानक से एक अलग संदेश रख सकते हैं:

इस आवेदन एक अवैध संचालन

प्रदर्शन किया है ... लेकिन क्या अपने कस्टम संदेश है कि किसी भी बेहतर है कहने जा रहा है?

हम अनिर्धारित रखरखाव के लिए बिना किसी चेतावनी के नीचे बंद कर रहे हैं, लेकिन आराम आश्वासन दिया कि यह कुछ भी नहीं इस उत्कृष्ट सॉफ्टवेयर

में एक दोष साथ करना था ...?

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

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