2011-01-07 17 views
26

मैंने क्लाइंटबेस को सेवा से कनेक्ट करने के लिए डब्ल्यूसीएफ का उपयोग करने के लिए लागू किया है। मैं फिर सेवा के साथ संवाद करने के लिए चैनल पर एक विधि बुला रहा हूँ।क्या डब्ल्यूसीएफ क्लाइंटबेस थ्रेड सुरक्षित है?

base.Channel.CalculateSomething(); 

क्या यह कॉल थ्रेड सुरक्षित है या क्या मुझे एकाधिक धागे चलाने पर इसे लॉक करना चाहिए?

धन्यवाद

उत्तर

3

हाँ चैनल पर विधि बुला सुरक्षित धागा है (ग्राहक के नजरिए से - सेवा परिप्रेक्ष्य सेवा कार्यान्वयन पर निर्भर करता है)। आप इस विधि को समानांतर में एकाधिक धागे से कॉल कर सकते हैं। यहां तक ​​कि स्वत: उत्पन्न करने वाली प्रॉक्सी आपको एसिंक्रोनस कॉल के लिए विधियां बनाने की पेशकश करेगी।

+1

क्या है आपके सबूत या कहने का कारण यह है कि यह थ्रेड-सुरक्षित है? मैं पूछ रहा हूं क्योंकि [एमएसडीएन पर क्लाइंटबेस क्लास] का अंत (http://msdn.microsoft.com/en-us/library/ms576141%28v=vs.110%29.aspx) यह कहता है कि यह नहीं है सुरक्षित धागा। – ChrisW

+0

@ChrisW: इसका अर्थ है कि 'क्लाइंटबेस' की गुणों का उपयोग करना थ्रेड सुरक्षित नहीं है लेकिन सेवा को कॉल करें (या यह दस्तावेज में एक बग हो सकता है - जो इतना दुर्लभ नहीं है)। सबसे पहले आप ग्राहक आधार के बिना कॉल कर सकते हैं - आपको केवल एक चैनल की आवश्यकता है। मेरे पास कोई सबूत नहीं है। मुझे विश्वास है कि रिमोट सेवा को कॉल करने के लिए किसी भी वैश्विक साझा डेटा को स्टोर करने की आवश्यकता नहीं है - अन्यथा डब्ल्यूसीएफ के पूरे ग्राहक पक्ष को बहुत खराब डिजाइन किया जाएगा। –

+0

क्या आंतरिक 'चैनल' थ्रेड-सुरक्षित होना जाता है? मुझे कल्पना है कि एक चैनल के पास कुछ मेमोरी बफर और नेटवर्क सॉकेट है; और जब तक कि यह समवर्ती उपयोगकर्ताओं (जैसे उनके अनुरोधों को अनुक्रमित करके) का समर्थन करने के लिए स्पष्ट रूप से डिज़ाइन नहीं किया गया है, तो यदि दो मेमोरी और सॉकेट को एक साथ लिखने का प्रयास करते हैं तो यह विनाशकारी होगा। – ChrisW

10

हां, यह थ्रेड-सुरक्षित है। हालांकि, आपको पता होना चाहिए कि डब्ल्यूसीएफ स्वचालित रूप से CalculateSomething के निष्पादन को क्रमबद्ध कर देगा जब इसे उसी ClientBase उदाहरण का उपयोग करके एक से अधिक धागे से कहा जाता है। तो यदि आप समवर्ती रूप से चलाने के लिए CalculateSomething की अपेक्षा कर रहे थे तो आपको अपने डिज़ाइन पर पुनर्विचार करना होगा। CalculateSomething विधि के लिए एसिंक्रोनस एपीआई बनाने के एक दृष्टिकोण के लिए this answer पर एक नज़र डालें।

+2

क्या आप इसका अर्थ समझ सकते हैं: "हालांकि, आपको पता होना चाहिए कि डब्लूसीएफ स्वचालित रूप से कैलकुलेट कुछ के निष्पादन को क्रमबद्ध कर देगा जब इसे एक ही क्लाइंटबेस उदाहरण का उपयोग करके एक से अधिक धागे से बुलाया जाता है।" धन्यवाद! – Erick

+4

इसका मतलब है कि डब्ल्यूसीएफ एक अनुक्रमिक तरीके से, एक साथ दूसरे के बाद कॉल करेगा, और साथ ही साथ नहीं (हालांकि वे प्रोग्रामेटिक दृष्टिकोण से ऐसा प्रतीत होते हैं)। –

+1

यह कहने का आपका सबूत या कारण क्या है कि यह थ्रेड-सुरक्षित है? और आप कैसे जानते हैं कि गणना करें कुछ स्वचालित रूप से क्रमबद्ध होता है: क्या यह क्लाइंट-साइड क्लाइंटबेस उदाहरण, या सर्वर/कार्यान्वयन पक्ष पर क्रमबद्ध है? मैं पूछ रहा हूं क्योंकि [एमएसडीएन पर क्लाइंटबेस क्लास] का अंत (http://msdn.microsoft.com/en-us/library/ms576141%28v=vs.110%29.aspx) यह कहता है कि यह नहीं है सुरक्षित धागा। – ChrisW

14

यहां उत्तरों पर अनुवर्ती टिप्पणियां मुझे अनिश्चित भी थीं, इसलिए मैंने कुछ और खुदाई की। यहाँ कुछ ठोस सबूत नहीं है कि ClientBase<T> धागा सुरक्षित है - this blog post की चर्चा एक WCF सेवा एक भी ग्राहक प्रॉक्सी की उपस्थिति में ठीक से प्रदर्शन से अधिक थ्रेड द्वारा किया जा रहा बनाने के लिए कैसे एक साथ (बोल्ड जोर मूल में है):

... हालांकि, वहाँ एक परिदृश्य में जहाँ एक PerCall सेवा पर एकाधिक करने के लिए ConcurrencyMode की स्थापना करता है, तो निम्न शर्तें लागू आपकी सेवा के लिए प्रवाह क्षमता में वृद्धि कर सकते है:

  1. ग्राहक है मल्टी-थ्रेडेड और एक ही प्रॉक्सी का उपयोग कर कई थ्रेड से आपकी सेवा में कॉल कर रहा है।

  2. ग्राहक और सेवा के बीच बाध्यकारी है एक बाध्यकारी सत्र है (उदाहरण के लिए, netTcpBinding, wsHttpBinding डब्ल्यू/विश्वसनीय सत्र, netNamedPipeBinding, आदि)।

इसके अलावा, इस पोस्ट में सबूत ब्रायन की अतिरिक्त टिप्पणी है कि WCF serializes किसी भी मल्टी-थ्रेडेड अनुरोध खंडन करने के लिए लगता है। पोस्ट एक साथ चलने वाले एकल क्लाइंट से कई अनुरोध दिखाता है - यदिConcurrencyMode.Multiple और InstanceContextMode.PerCall का उपयोग किया जाता है।

इस दृष्टिकोण के प्रदर्शन के प्रभाव के साथ-साथ कुछ विकल्पों के बारे में कुछ अतिरिक्त चर्चा here है।

+1

_ जबकि चैनल द्वारा बनाए गए चैनल और क्लाइंट थ्रेड-सुरक्षित हैं, वे तार के साथ एक से अधिक संदेश लिखने का समर्थन नहीं कर सकते हैं। स्रोत: [एमएस डॉक्स] (https://docs.microsoft।कॉम/एन-यूएस/डॉटनेट/फ्रेमवर्क/डब्ल्यूसीएफ/फीचर-स्टेटस/मिडिल-स्तरीय-क्लाइंट-एप्लिकेशन? व्यू = नेटफ्रेमवर्क -4.7.1) –

0

किसके लिए यह चिंता हो सकती है। डब्ल्यूसीएफ क्लाइंट बेस कम से कम इस कॉन्फ़िगरेशन में थ्रेड सुरक्षित हो सकता है। मैंने अन्य विन्यासों की कोशिश नहीं की।

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IWcfCallbacksContract), Namespace = "http://wcf.applicatin.srv/namespace")] 
public interface IWcfContract 
{ 
    [OperationContract] 
    CompositeReturnObject GetServerObject(); 
} 

सेवा:

public CompositeReturnObject GetServerObject() 
{ 
    CompositeReturnObject ret = new CompositeReturnObject("Hello"); 
    Thread.Sleep(10000); // Simulating long call 
    return ret; 
} 

ग्राहक:

private void GetData_Click(object sender, RoutedEventArgs e) 
{ 
    Console.WriteLine("Task 1 start: " + DateTime.Now.ToString("HH:mm:ss")); 

    Task.Factory.StartNew(() => { 
     var res = _proxy.GetServerObject(); 
     Console.WriteLine("Task 1 finish: " + DateTime.Now.ToString("HH:mm:s")); 
     Console.WriteLine(res.ToString()); 
     return; 
    } 
    ); 

    Thread.Sleep(2000); 

    Console.WriteLine("Task 2 start: " + DateTime.Now.ToString("HH:mm:ss")); 

    Task.Factory.StartNew(() => { 
     var res = _proxy.GetServerObject(); 
     Console.WriteLine("Task 2 finish: " + DateTime.Now.ToString("HH:mm:s")); 
     Console.WriteLine(res.ToString()); 
     return; 
    } 
    ); 
} 

और परिणाम:

कार्य 1 शुरू: 15:47:08
कार्य 2 शुरू: 15 : 47: 10

कार्य 1 खत्म: 15:47:18
नाम: वस्तु एक "हैलो"

कार्य 2 खत्म: 15:47:20
नाम: एक वस्तु "हैलो"

+0

इससे पता चलता है कि कॉल क्रमबद्ध नहीं हैं। यह साबित नहीं कर सका कि ग्राहक थ्रेड सुरक्षित है - यह एक संयोग हो सकता है। –

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