2009-05-07 14 views
5

मैं COM का उपयोग कर एक विरासत सी ++ एप्लिकेशन में सी # में लिखी गई सेवा का खुलासा करने जा रहा हूं। अप्रबंधित ग्राहक को त्रुटियों की रिपोर्ट करने का सबसे अच्छा तरीका क्या है? अपवाद फेंकना या बस एक त्रुटि मान वापस?प्रबंधित कोड को एक त्रुटि वापस करनी चाहिए या अप्रबंधित कोड में अपवाद फेंकना चाहिए?

धन्यवाद, Stefano

उत्तर

10

आपको अपवादों को फेंकना चाहिए। अपवादों को फ्रेमवर्क द्वारा HRESULTS में मैप किया गया है, और HRESULTs COM क्लाइंट में त्रुटियों को वापस करने का मानक तरीका है, इसलिए यह जाने का तरीका है।

प्रत्येक अपवाद प्रकार में एक HResult संपत्ति है। जब COM क्लाइंट से प्रबंधित प्रबंधित कोड अपवाद फेंकता है, तो रनटाइम HResult को COM क्लाइंट में पास करता है। यदि आप एप्लिकेशन-विशिष्ट HRESULT कोड चाहते हैं, तो आप अपना स्वयं का कस्टम अपवाद प्रकार बना सकते हैं और Exception.HResult संपत्ति सेट कर सकते हैं।

ध्यान देने योग्य एक बिंदु यह है कि एक कॉल क्लाइंट को अपवाद को फेंकने पर कॉल स्टैक जानकारी खो जाएगी। इसलिए COM क्लाइंट को प्रचार करने से पहले अपवाद लॉग इन करना एक अच्छा विचार हो सकता है।

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

इस दृष्टिकोण का एक अन्य लाभ यह है कि आप COM क्लाइंट के लिए COM के प्रतिबंधों के अनुरूप एपीआई और मानक .NET क्लाइंट के लिए एक और मानक API बना सकते हैं। उदाहरण के लिए, COM क्लाइंट संदर्भ द्वारा सरणी पास करने के लिए प्रतिबंधित हैं, जबकि संदर्भ द्वारा गुजरना .NET क्लाइंट के लिए निराश है।

उदाहरण:

[ 
ComVisible(true), 
GuidAttribute("..."), 
Description("...") 
] 
public interface IMyComVisibleClass 
{ 
    // Text from the Description attribute will be exported to the COM type library. 

    [Description("...")] 
    MyResult MyMethod(...); 

    [Description("...")] 
    MyOtherResult MyArrayMethod([In] ref int[] ids,...); 
} 
... 
[ 
ComVisible(true), 
GuidAttribute("..."), 
ProgId("..."), 
ClassInterface(ClassInterfaceType.None), 
Description("...") 
] 
public class MyComVisibleClass : IMyComVisibleClass 
{ 
    public MyResult MyMethod(...) 
    { 
     ... implementation without exception handling ... 
    } 

    public MyOtherResult MyArrayMethod(int[] ids,...) 
    { 
     ... input parameter does not use ref keyword for .NET clients ... 
     ... implementation without exception handling ... 
    } 

    MyResult IMyComVisibleClass.MyMethod(...) 
    { 
     // intended for COM clients only 
     try 
     { 
      return this.MyMethod(...); 
     } 
     catch(Exception ex) 
     { 
      ... log exception ... 
      throw; // Optionally wrap in a custom exception type 
     } 
    } 

    MyOtherResult IMyComVisibleClass.MyArrayMethod(ref int[] ids, ...) 
    { 
     // intended for COM clients only 
     try 
     { 
      // Array is passed without ref keyword 
      return this.MyArrayMethod(ids, ...); 
     } 
     catch(Exception ex) 
     { 
      ... log exception ... 
      throw; // Optionally wrap in a custom exception type 
     } 
    } 

} 
1

मैं यह कैसे विरासत आवेदन प्रतिक्रिया करेंगे पर निर्भर करता है लगता है। यदि यह त्रुटि वापसी मूल्यों को समझता है तो उस दृष्टिकोण के साथ जाएं। यदि ऐसा नहीं होता है, तो आपको अपवाद फेंकना होगा और आशा है कि यह उन्हें उचित तरीके से संभाल लें।

इसके अलावा, यदि यह एक खराब संदर्भ (उदाहरण के लिए शून्य संदर्भ) या अन्य महत्वपूर्ण त्रुटि है, तो मैं हमेशा एक अपवाद फेंक दूंगा। हालांकि, उपभोक्ताओं को पहले से जांच नहीं करनी चाहिए (उदा। एक खोज जो खाली हो जाती है उसे अपवाद नहीं फेंकना चाहिए) के लिए अपवादों से बचा जाना चाहिए।

3

यदि आपका COM एप्लिकेशन आपकी सी # सेवा में कॉल करते समय आईररइन्फो इंटरफेस का समर्थन करता है और यह एक पूरी तरह से आंतरिक परियोजना है तो अपवाद फेंकने की संभावना सबसे अच्छी शर्त है क्योंकि यह अधिकतर जानकारी को कैप्चर करता है। हालांकि COM ने परंपरागत रूप से स्थिति परिणामों को संवाद करने के लिए एचआर परिणामों पर भरोसा किया है और यदि सेवा अन्य स्रोतों पर प्रकाशित की जानी चाहिए तो बेहतर हो सकता है।

संपादित करें: मुझे जो के उत्तर को बेहतर पसंद है।

+0

अपवाद HRESULTS पर मैप किए जाते, तो यह सबसे अच्छा तरीका है। नीचे मेरी प्रतिक्रिया देखें। – Joe

1

सबसे अच्छा न्यायाधीश चाहे आप अपवादों का उपयोग करना चाहते हैं या मूल्य वापस कर रहे हैं। "अपवाद फेंकना" कई तरीकों से "लौटने वाले मूल्य" से अधिक है। लेकिन कुछ मामलों में मूल्य लौटने के लिए पर्याप्त होगा।

3

मैं दूसरों से सहमत हूं कि यह आपकी परियोजना को जानबूझकर बिना "हां या नहीं" उत्तर नहीं है।

यह इस तरह के रूप कारकों की एक संख्या पर निर्भर करेगा: (अपने ग्राहक को अपने अपवाद के बारे में क्या पता होना चाहिए यानी)

  • सुरक्षा
  • क्षमता
  • अनुरक्षणीयता ((यानी प्रसंस्करण समय महत्वपूर्ण है) यानी आप अपने अपवाद की स्थिति पार्स करने के लिए)

Here's a good blog post that discusses a number of subtle points about exception processing.

विरासत सी ++ कोड बदल सकते हैं

लेखक की सिफारिश की या तो दो तरीकों में से एक:

कोई एक:

  • वापसी एक त्रुटि दस्तावेज़।

या:

  • लॉग सर्वर पर अपवाद के बारे में सभी जानकारी।
  • नया अपवाद बनाएं जो जानकारी को संदर्भित करता है।
  • क्लाइंट साइड प्रोसेसिंग और रिपोर्टिंग के लिए क्लाइंट पर नया अपवाद भेजें।

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

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