2017-11-11 12 views
5

के लिए सिंगलटन पैटर्न डिजाइन मैं सिंगलटन पैटर्न डिज़ाइन के बारे में जानना चाहता हूं। मैं अपने सिंगलटन वर्ग से प्रति थ्रेड के लिए पृथक उदाहरण बनाना चाहता हूं। तो मैंने नीचे दो डिज़ाइन प्रदान किए।सी # थ्रेडस्टैटिक

यह

class Program 
{ 
    static void Main(string[] args) 
    { 
     Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode())); 
     Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode())); 
     Console.ReadLine(); 
    } 
} 
public sealed class SingletonClass 
{ 
    [ThreadStatic] 
    private static SingletonClass _instance; 

    public static SingletonClass Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new SingletonClass(); 
      } 
      return _instance; 
     } 
    } 
    private SingletonClass() 
    { 

    } 
} 

कार्य कर रहा है यह काम नहीं कर रहा (NullReferenceException फेंकने और उदाहरण नहीं बनाया जा रहा है।)

class Program 
{ 
    static void Main(string[] args) 
    { 
     Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode())); 
     Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode())); 
     Console.ReadLine(); 
    } 
} 
public sealed class SingletonClass 
{ 
    [ThreadStatic] 
    private static SingletonClass _instance = new SingletonClass(); 

    public static SingletonClass Instance 
    { 
     get 
     { 
      return _instance; 
     } 
    } 
    private SingletonClass() 
    { 

    } 
} 

मैं वास्तव में सोच रहा हूँ क्यों एक उदाहरण नहीं बनाई गई है दूसरे डिजाइन के लिए। क्या कोई इसे समझा सकता है?

+0

सी # कंपाइलर चर के लिए प्रारंभिक कार्यान्वयन को लागू करने के लिए एक स्थिर कन्स्ट्रक्टर उत्पन्न करता है। सीएलआर एक कठिन गारंटी प्रदान करता है कि यह केवल एक बार चलता है। आपको एक से अधिक बार चलाने के लिए उस 'नए' कथन की आवश्यकता है। –

+0

मुझे विश्वास है, भले ही यह काम करता है या आप इसे काम करने के लिए मिला है, यह अब एक सिंगलटन नहीं है। एक सिंगलटन एकल धागा एकल नहीं होना चाहिए। – CodingYoshi

+0

'कोडिंग योशी' सिंगलटन के विवरण में कहीं भी नहीं कहता है कि यह प्रति थ्रेड नहीं हो सकता है। पूर्व में अन्य भाषाओं में। 'डी' यह प्रति थ्रेड होने के लिए पूरी तरह से सामान्य होगा। चूंकि सबकुछ डिफ़ॉल्ट रूप से धागा-स्थानीय है। – Bauss

उत्तर

3

आपके प्रश्न का उत्तर ज्यादातर क्लास फ़ील्ड को आरंभ करने के तरीके से संबंधित है।

दूसरे उदाहरण में, _instance फ़ील्ड घोषणा में शुरू किया गया है। हर बार एक स्थैतिक क्षेत्र घोषणा में शुरू किया जाता है, एक स्थिर कन्स्ट्रक्टर बनाया जाएगा (यदि आपने इसे पहले ही घोषित नहीं किया है)। संकलन समय पर, प्रारंभिक स्थिर कन्स्ट्रक्टर में स्थानांतरित किया जाएगा। इसका मतलब यह है कि आप (कॉपी नहीं किया आईएल कोड के रूप में यह समझने के लिए कठिन हो जाएगा) कुछ इस तरह हो रही खत्म हो जाएगा:

public sealed class SingletonClass 
{ 
    [ThreadStatic] 
    private static SingletonClass _instance; 

    public static SingletonClass Instance 
    { 
     get 
     { 
      return _instance; 
     } 
    } 
    static SingletonClass() 
    { 
     _instance = new SingletonClass(); 
    } 
} 

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

4

[ThreadStatic] का उपयोग करने के बजाय आप ThreadLocal<T> का उपयोग कर सकते हैं जो अनिवार्य रूप से [ThreadStatic] के साथ आप क्या प्रयास कर रहे हैं।

public sealed class SingletonClass 
{ 
    private static ThreadLocal<SingletonClass> _instance; 

    static SingletonClass() 
    { 
     _instance = new ThreadLocal<SingletonClass>(() => new SingletonClass()); 
    } 

    public static SingletonClass Instance 
    { 
     get 
     { 
      return _instance.Value; 
     } 
    } 

    private SingletonClass() 
    { 

    } 
} 

देखें: https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx अधिक जानकारी के लिए।

संपादित करें: अपने प्रश्न का उत्तर देने के लिए।

सी # में जब कर रही:

private static SingletonClass _instance = new SingletonClass(); 

बावजूद अगर यह [ThreadStatic] के साथ या तो यह केवल एक ही स्थिर निर्माता जो SingletonClass के कहने सेट पैदा करेगा नहीं चिह्नित किया गया है।

सी # में प्रति थ्रेड स्थिर रचनाकार बनाने की क्षमता नहीं है।

यही है कि आप ThreadLocal<T> का उपयोग कर सकते हैं। यदि हम आपके कोड को उदाहरण के रूप में लेते हैं तो SingletonClass के लिए डिफ़ॉल्ट कन्स्ट्रक्टर अनिवार्य रूप से "thread-static" कन्स्ट्रक्टर बन जाता है।

+2

यह एक विकल्प प्रदान करता है लेकिन सवाल का जवाब नहीं देता है। – CodingYoshi

+0

मेरा उत्तर अपडेट किया गया – Bauss

+0

धन्यवाद, मुझे लगता है, यह नेस्टेड धागे के लिए एक अच्छा विकल्प है। मैं थ्रेडलोकल के साथ अपना प्रोजेक्ट कोड संपादित करूंगा। लेकिन फिर भी मैं अपना प्रश्न समझना चाहता हूं। – lucky

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

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