2010-01-11 16 views
27

तो यहाँ मेरी वर्गों में से एक से एक अंश है:एक पठनीय स्थिर क्षेत्र शून्य कैसे हो सकता है?

[ThreadStatic] 
    readonly static private AccountManager _instance = new AccountManager(); 

    private AccountManager() 
    { 
    } 

    static public AccountManager Instance 
    { 
     get { return _instance; } 
    } 

आप देख सकते हैं, यह एक सिंगलटन-प्रति-धागा है - अर्थात उदाहरण ThreadStatic विशेषता के साथ चिह्नित है। उदाहरण स्थिर निर्माण के हिस्से के रूप में भी तत्काल है।

तो मामले जा रहा है कि, यह कैसे संभव है कि मैं जब मैं उदाहरण संपत्ति इस्तेमाल करने की कोशिश मेरी ASP.NET MVC आवेदन में एक NullReferenceException हो रही है?

+1

शो जहां आप इसे उपयोग करने के लिए कोशिश कर रहे हैं, कि मदद मिल सकती है, जहां nullref – curtisk

+0

यह एक आवरण से ASP.NET अनुप्रयोग में उपयोग किया जा रहा है पर चिह्नित करने है - सार्वजनिक IAccount जाओ (स्ट्रिंग ईमेल) { वापसी खाता प्रबंधक .Instance।जाओ (ईमेल); } यह मैंने सोचा जितना मुश्किल हो सकता है; वेब सर्वर (वीएस में अंतर्निहित एक) को मारना और एप्लिकेशन को पुनरारंभ करने से समस्या गायब हो गई ... – gerrod

उत्तर

38

MSDN ThreadStaticAttribute का हवाला देते हुए:

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

+0

संदर्भ प्रदान करने के लिए +1 –

+0

सहमत है, मैंने इसे उत्तर के रूप में चिह्नित किया है। धन्यवाद ऑस्टिन! – gerrod

1

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

12

यह ThreadStatic विशेषता के एक भ्रामक हिस्सा है। भले ही यह प्रति थ्रेड मान बनाता है, इनटाइलाइजेशन कोड केवल धागे में से एक पर चलाया जाता है। इस मान को एक्सेस करने वाले सभी अन्य थ्रेड प्रारंभिक कोड के परिणामस्वरूप उस प्रकार के लिए डिफ़ॉल्ट हो जाएंगे।

मूल्य प्रारंभ करने के बजाय, इसे उस संपत्ति में लपेटें जो आपके लिए प्रारंभिकता करता है।

[ThreadStatic] 
readonly static private AccountManager _instance; 

private AccountManager() 
{ 
} 

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

क्योंकि मूल्य _instance धागा प्रति अद्वितीय है, कोई ताला संपत्ति में आवश्यक है और यह किसी भी अन्य lazily प्रारंभ मूल्य की तरह व्यवहार किया जा सकता है।

+0

धन्यवाद जेरेड; मेरा समाधान आपके जैसा ही दिखता है लेकिन मुझे थ्रेडस्टैटिक के बारे में पता नहीं था। तो मुझे मूर्ख बनाओ! – gerrod

8

आपने यहां क्लासिक [ThreadStatic] "101" मारा है।

स्थिर प्रारंभकर्ता केवल एक बार भी हालांकि यह [ThreadStatic] के रूप में चिह्नित किया गया है, ताकि अन्य धागे में सक्रिय होगा,, (अलावा पहले से) इस uninitialised देखेंगे।

0

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

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