2009-11-10 13 views
6

मुझे वेब पर मेरे प्रश्न के मिश्रित उत्तरों मिल रहे हैं। प्रश्न पर विस्तृत करने के लिए:सिल्वरलाइट 3 में डब्ल्यूसीएफ सेवा क्लाइंट प्रॉक्सी का उचित जीवन चक्र क्या है?

  1. क्या मुझे एक बार सिंक्रोनस आमंत्रण, या प्रति सिल्वरलाइट ऐप प्रति बार एक सेवा क्लाइंट प्रॉक्सी को तुरंत चालू करना चाहिए?
  2. क्या मुझे सेवा क्लाइंट प्रॉक्सी को स्पष्ट रूप से बंद करना चाहिए (जैसा कि मैं अपने एएसपी.नेट एमवीसी अनुप्रयोग में डब्ल्यूसीएफ सेवाओं को सिंक्रनाइज़ करता हूं)?

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

+0

उत्तर शायद आपकी सेवा पर निर्भर करता है। प्रॉक्सी बनाना महंगा है, लेकिन उस एकल प्रॉक्सी का ट्रैक रखना और किसी भी त्रुटि को प्रबंधित करना मुश्किल हो सकता है। – Bryant

उत्तर

0

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

+0

सिल्वरलाइट में उपयोग किए जाने वाले एसिंक्रोनस डब्ल्यूसीएफ कॉल की दुनिया में, "तत्काल बाद" का अर्थ क्या है? एसिंक्रोनस कॉल शुरू करने के बाद इसे बंद करें, या पूरा होने पर इसे बंद करें? यदि उत्तरार्द्ध, यह सवाल उठता है कि क्या होता है यदि यह कभी पूरा नहीं होता है। – Trinition

3

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

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

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

private static int clientsOpen; 
    public static int ClientsOpen 
    { 
     get 
     { 
      return clientsOpen; 
     } 
     set 
     { 
      clientsOpen = value; 
      Debug.Assert(clientsOpen <= 1, "Bad things seem to happen when there's more than one open client."); 
     } 
    } 

    public static RoomServiceClient GetRoomServiceClient() 
    { 
     ClientsCreated++; 
     ClientsOpen++; 
     Logger.LogDebugMessage("Clients created: {0}; Clients open: {1}", ClientsCreated, ClientsOpen); 
     return new RoomServiceClient(GetDuplexHttpBinding(), GetDuplexHttpEndpoint()); 
    } 

    public static void TryClientClose(RoomServiceClient client, bool waitForPendingCalls, Action<Exception> callback) 
    { 
     if (client != null && client.State != CommunicationState.Closed) 
     { 
      client.CloseCompleted += (sender, e) => 
      { 
       ClientsClosed++; 
       ClientsOpen--; 
       Logger.LogDebugMessage("Clients closed: {0}; Clients open: {1}", ClientsClosed, ClientsOpen); 
       if (e.Error != null) 
       { 
        Logger.LogDebugMessage(e.Error.Message); 
        client.Abort(); 
       } 
       closingIntentionally = false; 
       if (callback != null) 
       { 
        callback(e.Error); 
       } 
      }; 
      closingIntentionally = true; 
      if (waitForPendingCalls) 
      { 
       WaitForPendingCalls(() => client.CloseAsync()); 
      } 
      else 
      { 
       client.CloseAsync(); 
      } 
     } 
     else 
     { 
      if (callback != null) 
      { 
       callback(null); 
      } 
     } 
    } 

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

0

डब्ल्यूसीएफ में कॉन्फ़िगरेशन सेटिंग्स हैं जो बताती हैं कि कॉल करने के लिए कितनी देर तक प्रतीक्षा करनी चाहिए, मेरी सोच यह है कि जब यह अनुमति समय में पूरा नहीं होता है तो AsyncClose इसे बंद कर देगा। इसलिए क्लाइंट को कॉल करें। AsyncClose()।

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