मैं वी 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);
}
}
}
कष्टप्रद हिस्सा है, निश्चित रूप से, यदि आप केवल एक कनेक्शन है है, तो आप जब कि कनेक्शन अनजाने बंद कर देता है के लिए जाल की जरूरत है और इसे फिर से खोलने की कोशिश करो। और फिर आपको उन सभी कॉलबैक को फिर से शुरू करने की आवश्यकता है जिन्हें आपके विभिन्न वर्गों को संभालने के लिए पंजीकृत किया गया था। यह वास्तव में इतना मुश्किल नहीं है, लेकिन यह सुनिश्चित करने के लिए परेशान है कि यह सही हो गया है। और निश्चित रूप से, असंभव नहीं होने पर उस हिस्से का स्वचालित परीक्षण मुश्किल है। । ।
उत्तर शायद आपकी सेवा पर निर्भर करता है। प्रॉक्सी बनाना महंगा है, लेकिन उस एकल प्रॉक्सी का ट्रैक रखना और किसी भी त्रुटि को प्रबंधित करना मुश्किल हो सकता है। – Bryant