2011-03-28 12 views
15

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

यह मैं मेरे सवाल के लिए लाता है - हम ग्राहक के चैनल को संभालने के लिए सबसे अच्छा तरीका है एक गलती राज्य में प्रवेश तय करने की कोशिश कर रहे हैं। कुछ चारों ओर खोज के बाद, हम इस के साथ आ गया है:

if(client.State = CommuncationState.Faulted) 
{ 
    client = new Client(); 
} 

try 
{ 
    client.SomeMethod(); 
} 
catch //specific exceptions left out for brevity 
{ 
    //logging or whatever we decide to do 
    throw; 
} 

लेकिन यह सच है कि, कम से कम हमारे मामले में, भले ही सेवा ग्राहक नीचे है दिखाएगा की वजह से काम नहीं करता है Open राज्य जब तक आप वास्तव में इसका उपयोग करके कॉल करने का प्रयास नहीं करते हैं, उस बिंदु पर यह Faulted स्थिति में प्रवेश करता है।

तो यह हमें कुछ और करने के लिए छोड़ देता है। एक और विकल्प जिसके साथ हम आए थे:

try 
{ 
    client.SomeMethod(); 
} 
catch 
{ 
    if(client.State == CommunicationState.Faulted) 
    { 
     //we know we're faulted, try it again 
     client = new Client(); 
     try 
     { 
      client.SomeMethod(); 
     } 
     catch 
     { 
      throw; 
     } 
    } 
    //handle other exceptions 
} 

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

ध्यान में रखने के लिए एक और बात - ग्राहक की तत्कालता और यह सभी जांच और हैंडलिंग ग्राहक के लिए एक रैपर वर्ग में होती है। अगर हम ऐसा करने का इरादा रखते हैं, तो यह ऐप के लिए पारदर्शी है - कॉल करने और उनसे अपवादों को संभालने के लिए वहां कोई विशेष कोड की आवश्यकता नहीं है।

+0

ग्राहक को दोषपूर्ण स्थिति में प्रवेश करने का कारण क्या है? मैं हमेशा एक डब्ल्यूसीएफ सेवा सामान्य रूप से एक गलती वापस करने में सक्षम रहा हूं और ग्राहक इसके व्यापार के बारे में जारी रख सकता है। क्या सर्वर प्रतिक्रिया नहीं दे रहा है या कुछ? – Tridus

+0

इस मामले में, हम एएसपी.NET सदस्यता का उपयोग कर रहे हैं, और हम "userIsOnlineTimeWindow" विशेषता से अधिक होकर इसमें भाग गए। जाहिर है कि उस मामले में उपयोगकर्ता को केवल लॉगिन पेज पर रीडायरेक्ट करना होगा, लेकिन हम यह सुनिश्चित करने की कोशिश कर रहे हैं कि हम किसी भी अन्य परिस्थिति के लिए तैयार हैं जिसमें हम एक दोषपूर्ण स्थिति में शामिल हो सकते हैं। – Zannjaminderson

उत्तर

18

आपके प्रश्न का उत्तर करने के लिए, अगर आप इस तरह ChannelFactory संपत्ति के Faulted event संभाल कर सकते हैं:

client.ChannelFactory.Faulted += new EventHandler(ChannelFactory_Faulted); 

है कि आप जो कुछ भी प्रवेश/सफाई है कि आप क्या करने की जरूरत प्रदर्शन करने के लिए अनुमति चाहिए।

एक सामान्य सिफारिश के रूप में, आपको चैनल की अवधि के लिए चैनल को नहीं छोड़ना चाहिए, इसलिए सुनिश्चित करें कि आप इसे समाप्त करने के बाद चैनल को ठीक से बंद कर रहे हैं (अपवाद पर निरस्त कर रहे हैं)।

इसके अलावा, यदि संभव हो, तो विजुअल स्टूडियो एड सर्विस रेफरेंस का उपयोग न करें, या कम से कम कोड/कॉन्फ़िगरेशन को साफ़ करने पर विचार करें।मैं अनुशंसा करता हूं कि यदि आप प्रॉक्सी कार्यान्वयन का उपयोग करना चाहते हैं, तो ClientBase से प्राप्त करके अपना स्वयं का निर्माण करें, या ChannelFactory कार्यान्वयन का उपयोग करें। चूंकि आप एक रैपर वर्ग का उल्लेख करते हैं, इसलिए मैं अनुशंसा करता हूं कि आप एक चैनल फैक्टरी का उपयोग करें और अपनी सफाई आवश्यकताओं के लिए Faulted event को संभालें।

+0

उत्तर के लिए धन्यवाद। मैंने बहुत से लोगों को प्रत्येक कॉल के लिए क्लाइंट चैनल खोलने और बंद करने के बारे में बात करते हुए देखा है और मैं सोच रहा हूं कि इस तरह से ऐसा करने के कारण क्या हैं? – Zannjaminderson

+2

कारण यह है कि आप केवल अपनी सेवा के लिए कई समवर्ती कॉल और समवर्ती सत्र कर सकते हैं। इसलिए यदि आपके वेब ऐप में प्रत्येक सत्र में एक खुला सत्र है, तो आप जल्दी से डिफ़ॉल्ट सीमा को हिट करेंगे और इसे बदलने की जरूरत है, और प्रदर्शन भुगतना होगा। इन (और अन्य) सेटिंग्स को अनुकूलित करने के बारे में अधिक जानकारी के लिए इसे देखें: http://msdn.microsoft.com/en-us/library/ee377061(v=bts.10).aspx – BrandonZeider

+0

धन्यवाद। मैं चैनलफैक्टरी पर कुछ और पढ़ रहा हूं और ऐसा लगता है कि हम उस दिशा को आगे बढ़ाएंगे। – Zannjaminderson

11

ग्राहक प्रॉक्सी पर .Faulted घटना से निपटने, जैसे प्रयास करें:

((ICommunicationObject)client).Faulted += new EventHandler(client_Faulted); 

private void client_Faulted(object sender, EventArgs e) 
{ 
    client = new Client(); 
    ((ICommunicationObject)client).Faulted += new EventHandler(client_Faulted); 
} 

यह तत्काल चैनल दोष, आप फिर से खुल यह करने के लिए एक मौका देने के सक्रिय होना चाहिए।

आपको अभी भी प्रत्येक कॉल को client विधि को रीक-कैच ब्लॉक में लपेटना चाहिए, और शायद इसे while() लूप में भी लपेटना चाहिए जो कॉल एन बार पुनः प्रयास करता है, फिर विफलता लॉग करता है। ईजी:

bool succeeded = false; 
int triesLeft = 3; 
while (!succeeded && triesLeft > 0) 
{ 
    triesLeft--; 
    try 
    { 
     client.SomeMethod(); 
     succeeded = true; 
    } 
    catch (exception ex) 
    { 
     logger.Warn("Client call failed, retries left: " + triesLeft; 
    } 
} 
if (!succeeded) 
    logger.Error("Could not call web service"); 

मेरी कोड में मैं जहाँ तक एक ManualResetEvent उपयोग करने के लिए है, जबकि() पाश ब्लॉक करने के लिए जब तक client_Faulted ईवेंट हैंडलर को client प्रॉक्सी फिर से बनाने का अवसर मिल सके चले गए हैं।

+1

'Faulted' ईवेंट से सदस्यता समाप्त करने के बारे में क्या? यह कहाँ किया जाना चाहिए? – itsho

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