2009-01-10 9 views
8

यदि मैं ऐसा करना चाहता हूं तो अपवाद को एक स्तर पर फेंक दें?सी # क्या मुझे फेंकने के लिए ट्रे/कैच की आवश्यकता है?

private void TryCatch() 
{ 
    try 
    { 
     foo(); 
    } 
    catch (Exception ex) 
    { 
     throw; 
    } 
} 

private void NoTryCatch() 
{ 
    foo(); 
} 

इन दोनों तरीकों में एक ही नहीं कर रहे हैं?

यदि TryCatch में कोई अपवाद होता है तो इसे एक स्तर पर फेंक दिया जाएगा और यदि NoTryCatch में कोई अपवाद होता है, तो अपवाद भी एक स्तर को फेंक दिया जाएगा।

यह प्रश्न रीशेपर का उपयोग करने के बाद आया और यह ध्यान में रखते हुए कि यह प्रयास/पकड़ ब्लॉक को हटाने के लिए सुझाव दिया गया था क्योंकि यह अनावश्यक था।

उत्तर

1

ये दो विधियां अनिवार्य रूप से वही हैं। इस मामले में ReSharper अपने सुझाव के साथ सही था।

3

नहीं, आपको कोशिश करने की आवश्यकता नहीं है। एकमात्र कारण आप पहले फ़ंक्शन का उपयोग करना चाहते हैं, यदि आप फ़ंक्शन को आगे बढ़ाने से पहले कुछ लॉगिंग या संसाधनों को रिलीज़ करना चाहते हैं।

0

रीशेर्पर सही है। जब तक कि आप वास्तव में अपवाद के बारे में कुछ पकड़ने और कुछ करने का इरादा नहीं रखते हैं, तब तक कोई भी बिंदु नहीं है .. कोशिश करें ब्लॉक।

+0

जब तक आप अंत में कुछ सफाई काम करने के लिए ब्लॉक की जरूरत है:

सबसे अच्छा एक अपवाद को पकड़ने के लिए कारण स्टैक ट्रेस करने के लिए प्रसंग जोड़ने के लिए, की तरह है। –

+1

@Fred: वह 'आखिरकार कोशिश करें' तो 'try..catch' नहीं, सही होगा? – AnthonyWJones

0

हां, प्रयास पकड़ ब्लॉक अनावश्यक है। अपवाद को संभालने के लिए प्रयास/पकड़ मिलने तक ढेर केवल अवांछित होगा।

0

यदि आप जो कुछ करते हैं वह अपवाद को दोबारा हटा देता है तो आपको कोशिश/पकड़ ब्लॉक की आवश्यकता नहीं होती है। आम तौर पर आपको केवल उन अपवादों को पकड़ना चाहिए जब आप उन्हें संभाल सकें। अन्यथा उन्हें ऊपर की ओर प्रचार करने दें।

19

हां, ये विधियां काफी अधिक हैं (*) वही हैं। केवल अंतर यह है कि पहले में ब्रेकपॉइंट रखना आसान है। मैं हमेशा दूसरे के साथ जाऊंगा जब तक कि मुझे वास्तव में वहां तोड़ने की ज़रूरत नहीं होती और केवल वहां (जैसा कि तुरंत उस प्रकार के किसी भी अपवाद को फेंक दिया गया था, जो आसान होगा)। यहां तक ​​कि अगर मैंने पहले कभी भी इस्तेमाल किया है, तो भी मैं इसे कोड करने से पहले इसे दूसरे फॉर्म में वापस रखूंगा।

(*) जेआईटी उन्हें कैसे संभालता है इस मामले में कुछ मतभेद हो सकते हैं। पहला आईएल के साथ खत्म हो जाएगा, जो इनलाइनिंग आदि के अवसरों को प्रभावित करेगा।

संपादित करें: मैं माइक्रो-बेंचमार्किंग का थोड़ा सा विरोध नहीं कर सकता।

सरल विधि: 504, 495, 489

using System; 
using System.Diagnostics; 
using System.Runtime.CompilerServices; 

public class Test 
{ 
    const int Iterations = 1000000000; 

    static void Main() 
    { 
     Stopwatch sw; 

     sw = Stopwatch.StartNew(); 
     for (int i=0; i < Iterations; i++) 
     { 
      SimpleMethod(); 
     } 
     sw.Stop(); 
     Console.WriteLine("Simple method: {0}", sw.ElapsedMilliseconds); 

     sw = Stopwatch.StartNew(); 
     for (int i=0; i < Iterations; i++) 
     { 
      NoInlining(); 
     } 
     sw.Stop(); 
     Console.WriteLine("No inlining: {0}", sw.ElapsedMilliseconds); 

     sw = Stopwatch.StartNew(); 
     for (int i=0; i < Iterations; i++) 
     { 
      TryCatchThrow(); 
     } 
     sw.Stop(); 
     Console.WriteLine("try/catch/throw: {0}", sw.ElapsedMilliseconds); 
    } 

    static void SimpleMethod() 
    { 
     Foo(); 
    } 

    [MethodImpl(MethodImplOptions.NoInlining)] 
    static void NoInlining() 
    { 
    } 

    static void TryCatchThrow() 
    { 
     try 
     { 
      Foo(); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 

    static void Foo() {} 
} 

साथ /o+ /debug-

परिणाम (तीन रन) संकलित: यह ट्राई/कैच की तरह दिखता है/फेंक सिर्फ अक्षम करने इनलाइन किए जाने वाले की तुलना में प्रदर्शन पर nastier असर पड़ता है
नहीं इनलाइनिंग: 2977, 3060, 3019
ट्राई/कैच/फेंक: 5274, 4543, 5145

+0

मेरा मानना ​​है कि किसी भी कोशिश/पकड़ इनलाइनिंग को रोक देगा। शोध ... – JaredPar

+0

यह मेरा अनुमान भी था, हालांकि मेरे पास शोध के लिए ऊर्जा नहीं थी। ऐसा नहीं है कि जेआईटी को यह ध्यान देने से रोकने के लिए कुछ भी है कि इस मामले में कोशिश/पकड़ अनावश्यक है, मुझे संदेह है, और इसे अलग कर रहा है ... –

+0

मेरे दावे का समर्थन करने के लिए कुछ भी नहीं मिला। मुझे विश्वास है कि यह या तो फेंक रहा है या कोशिश/पकड़ इनलाइन रोकता है। मुझे संदेह है कि यह वास्तव में फेंक बनाम पकड़ सकता है। – JaredPar

0

कुछ मैं के बारे में सोचा है, लेकिन मुझे यकीन नहीं था कि 100% इसलिए मैं जांच करने गया। मैं कभी-कभी सही था।

जाहिर है, यदि आप अपवाद को फिर से फेंक देते हैं, तो आपका कोड क्या कर रहा है, तो आप स्टैक-ट्रेस को बदल सकते हैं। सबसे पहले, अगर आप throw ex; लिखना चाहते थे जो स्टैक-ट्रेस रीसेट करेगा। दूसरा, यहां तक ​​कि throw; लिखते समय भी ऐसे मामले हो सकते हैं जहां जानकारी गुम होती है। इसे article और कुछ user comments पर इसके बाद देखें।

बेशक, इनमें से अधिकतर मुद्दे स्टैक-ट्रेस और लाइन-नंबर से संबंधित हैं, जो महत्वपूर्ण हैं, लेकिन मैंने सोचा कि यह प्रदर्शन को प्रभावित करेगा, न केवल इनलाइनिंग (या इसकी कमी) के कारण, बल्कि यह भी पूरे अपवाद को पकड़ने और ऊपर की ओर फेंकने के कारण, लेकिन मुझे इस पर कुछ भी ठोस नहीं मिला।

1

वे वास्तव में वही नहीं हैं। Throw अपने स्वयं के या throw ex स्टैक ट्रेस जानकारी के साथ गड़बड़ कर और डीबगिंग को कठिन बना सकता है।

try { 
    Foo(); 
} 
catch (Exception e) { 
    throw new BetterException("I did something slightly silly", e); 
} 
संबंधित मुद्दे