2013-03-05 7 views
10

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

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace LazySingleton 
{ 
    public class CLazySingleton 
    { 
     private static readonly Lazy<CLazySingleton> _instance 
      = new Lazy<CLazySingleton>(() => new CLazySingleton()); 
     private static readonly object ThreadLock = new object(); 
     public static string abc; 
     //I will use the service connection object in place of 'abc' in the application 
     //assume that 'abc' is storing the connection object  

     private CLazySingleton() 
     { } 

     public static CLazySingleton Instance 
     { 
      get 
      { 
       if (abc == null) 
       { 
        lock (ThreadLock) 
        { 
         //Make the connection 
         abc = "Connection stored in this variable"; 
         Console.WriteLine("Connection Made successfully"); 
         return _instance.Value; 
        }      
       } 
       else 
       { 
        return _instance.Value; 
       } 
      } 
     } 
    } 
} 

मेरे सवाल कर रहे हैं: 1. इस कोड को कई की देखभाल करने में सक्षम हो सकते हैं

CLazySingleton ins = CLazySingleton.Instance; 
string connection = CLazySingleton.abc; 

नीचे सिंगलटन वर्ग के लिए कोड है: मैं इस प्रकार उदाहरण पाने के लिए कोशिश कर रहा हूँ धागे एक ही समय में उदाहरण प्राप्त करने की कोशिश कर रहे हैं? यह वर्तमान में मेरी सबसे बड़ी चिंता है। 2. क्या इसके लिए मेरे पास बेहतर समाधान हो सकता है? 3. क्या मुझे यहां 'लॉक' का उपयोग करने की ज़रूरत है या आलसी दृष्टिकोण का उपयोग करना उदाहरण प्राप्त करने की कोशिश कर रहे मल्टीथ्रेड का ख्याल रखता है?

किसी भी मदद की सराहना की जाएगी।

धन्यवाद!

+1

जॉन स्कीट द्वारा इस लेख चेक बाहर, है। यह सिंगलटन पैटर्न पर चर्चा करने का अच्छा काम करता है। http://www.yoda.arachsys.com/csharp/singleton.html – juharr

+0

मुझे आपके दृष्टिकोण पर कुछ संदेह हैं। कनेक्शन के लिए आपको सिंगलटन को बनाए रखने की आवश्यकता क्यों है? क्या कोई समस्या है यदि प्रत्येक थ्रेड को अपना प्रॉक्सी/कनेक्शन मिलता है? और चूंकि यह एक वेब सेवा है, इसलिए यदि आप कई कनेक्शन बनाते हैं तो मुझे कोई समस्या नहीं दिखती है। --- बेहतर समझने के लिए कि आपका 'कनेक्शन' किस तरह का ऑब्जेक्ट है? – thewpfguy

+0

आपको लॉक की आवश्यकता नहीं है – Rafa

उत्तर

5

सरल उपयोग ThreadSafetyMode

Lazy<MergeSort> ty = new Lazy<MergeSort>(LazyThreadSafetyMode.ExecutionAndPublication); 
+6

आलसी का डिफ़ॉल्ट कन्स्ट्रक्टर LazyThreadSafetyMode.ExecutionAndPublication का उपयोग करता है, यह डिफ़ॉल्ट रूप से थ्रेड सुरक्षित है। – Phil

+0

धन्यवाद, मैं निश्चित रूप से यह कोशिश करूँगा। –

8

माइक्रोसॉफ्ट के Lazy Initialization प्रलेखन के अनुसार, अनुभाग "थ्रेड-सुरक्षित प्रारंभ" शीर्षक के तहत:

डिफ़ॉल्ट रूप से, Lazy वस्तुओं धागा सुरक्षित हैं।

इसे ध्यान में रखते

, अपने abc क्षेत्र स्थिर होने की जरूरत नहीं। चूंकि आप अपने सिंगलटन को चालू करने के लिए Lazy<T> का उपयोग कर रहे हैं, तो CLazySingleton कन्स्ट्रक्टर में अपना कनेक्शन प्रारंभ करना सुरक्षित है।

+0

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

+0

मुझे लगता है कि सिंगलटन का उपयोग करना सही पैटर्न नहीं है, वास्तव में आपको इस तरह से अपने कनेक्शन को प्रबंधित करने की आवश्यकता नहीं है। और, क्या आप वाकई एक वेब सेवा बुला रहे हैं, क्योंकि आप किस प्रकार का टाइमआउट यहां उल्लेख करते हैं? – thewpfguy

3

क्या यह कोड एक ही समय में उदाहरण प्राप्त करने की कोशिश कर रहे कई धागे का ख्याल रखने में सक्षम होगा?

आपके परिदृश्य में "abc" फ़ील्ड दो बार शुरू हो सकता है। स्थिति की कल्पना करो, कि "एबीसी" चर शून्य है। पहला थ्रेड मान असाइनमेंट से पहले "लॉक" ब्लॉक के अंदर होगा। दूसरा थ्रेड लॉक से पहले इंतजार कर रहा है। तो पहला धागा "एबीसी" शुरू करेगा और दूसरा थ्रेड इसे फिर से शुरू करेगा (शून्य के लिए आपकी जांच लॉक के बाहर है, यही कारण है)। लेकिन शायद यह ऐसा कुछ नहीं है जिसे आपको डरना चाहिए।

क्या मेरे पास इसके लिए बेहतर समाधान हो सकता है?

हाँ आप कर सकते हैं। मुझे इस उत्तर के अंतिम ब्लॉक में इसका वर्णन करने दें।

क्या मुझे यहां 'लॉक' का उपयोग करने की आवश्यकता है या आलसी दृष्टिकोण का उपयोग करने से मल्टीथ्रेड का उदाहरण प्राप्त करने का प्रयास किया जाता है?

आलसी वर्ग में मूल्य संपत्ति का निर्माण थ्रेड सुरक्षित है। आपके परिदृश्य में मैं आलसी <> कक्षा की संपत्ति IsValue का लाभ उठाऊंगा। आपको अभी भी थ्रेड लॉक ऑब्जेक्ट की आवश्यकता होगी।बस एक और बात है कि एक बार आप Lazy < का मूल्य संपत्ति का उपयोग> वर्ग, IsValueCreated संपत्ति सच वापस आ जाएगी (है कि चाल है ;-))

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace LazySingleton 
{ 
    public class CLazySingleton 
    { 
     private static readonly Lazy<CLazySingleton> _instance 
      = new Lazy<CLazySingleton>(() => new CLazySingleton()); 
     private static readonly object ThreadLock = new object(); 
     public static string abc; 
     //I will use the service connection object in place of 'abc' in the application 
     //assume that 'abc' is storing the connection object  

     private CLazySingleton() 
     { } 

     public static CLazySingleton Instance 
     { 
      get 
      { 
       if (_instance.IsValueCreated) 
       { 
        return _instance.Value; 
       } 
       lock (ThreadLock) 
       { 
        if (abc == null) 
        { 
         abc = "Connection stored in this variable"; 
         Console.WriteLine("Connection Made successfully"); 
        } 
       } 
       return _instance.Value; 
      } 
     } 
    } 
} 
संबंधित मुद्दे