2009-09-16 7 views
7

मुझे लगता है कि मुझे एएसपी.Net एप्लिकेशन में स्थैतिक वस्तुएं कैसे बनी रहती हैं, यह समझने में कुछ मदद चाहिए। एक वर्ग पुस्तकालय मेंउपयोगकर्ता सत्रों के बीच मेरे एएसपी.Net स्थिर फ़ंक्शन का "संदर्भ" क्रॉसओवर क्यों है?

someFile.cs: एक वर्ग पुस्तकालय में

public delegate void CustomFunction(); 

public static class A { 
    public static CustomFunction Func = null; 
} 

someOtherFile.cs:

public class Q { 
    public Q() { 
     if (A.Func != null) { 
      A.Func(); 
     } 
    } 
} 

कुछ ASP.Net पेज:

Page_Init { 
    A.Func = MyFunc; 
} 

public void MyFunc() { 
    System.IO.File.AppendAllText(
     "mydebug.txt", DateTime.Now.ToString("hh/mm/ss.fff", Session.SessionID)); 
} 

Page_Load { 
    Q myQ = new Q(); 
    System.Threading.Thread.Sleep(20000); 
    mQ = new Q(); 
} 
मैं इस परिदृश्य है

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

यदि मैं एक उपयोगकर्ता सत्र चलाता हूं, तो जब वह कॉलबैक फ़ंक्शन पर कॉल के बीच सो रहा है, तो दूसरा सत्र सत्र शुरू करें, जब पहला सत्र सोने से वापस आता है तो यह दूसरे उपयोगकर्ता सत्र से सत्र आईडी उठाता है। यह कैसे संभव हो सकता है?

mydebug.txt के आउटपुट:

01/01/01.000 abababababab (session #1, first call) 
01/01/05.000 cdcdcdcdcdcd (session #2, first call - started 5 seconds after session #1) 
01/01/21.000 cdcdcdcdcdcd (session #1 returns after the wait but has assumed the function context from session #2!!!!!) 
01/01/25.000 cdcdcdcdcdcd (session #2 returns with its own context) 

क्यों समारोह के संदर्भ (जिसका अर्थ है, अपने स्थानीय डेटा, आदि) एक से दूसरे उपयोगकर्ता के सत्र से ओवरराइट किया जा रहा है?

+0

धन्यवाद, हर कोई, मदद के लिए। StackOverflow नियम। :) –

उत्तर

2

एक समाधान पर विचार कर सकते [ThreadStatic] का उपयोग कर रहा है।

http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(VS.71).aspx

यह धागा प्रति अपने स्टैटिक्स कर देगा। हालांकि cavaets हैं तो आप परीक्षण करना चाहिए।

+0

प्रारंभिक मूल्यों के बारे में आपके लिंक में एमएसडीएन नोट के अलावा, चेतावनी क्या हैं? –

+0

यह एएसपी.नेट में काम नहीं करेगा। आप भविष्यवाणी नहीं कर सकते कि कौन सा धागा किसी दिए गए अनुरोध की सेवा करेगा। – Brannon

+0

@ ब्रैनन - लेकिन क्या हमें गारंटी नहीं है कि एक धागा एक ही अनुरोध की सेवा करेगा? मुझे लगता है कि यह मेरा मुद्दा है - कि एक थ्रेड का MyFunc ऑपरेशन के बीच में MyFunc के किसी अन्य धागे के असाइनमेंट द्वारा बदल गया है। –

11

एक asp.net साइट के लिए प्रत्येक अनुरोध में आता है और उसके अपने धागे पर संसाधित किया जाता है। लेकिन उनमें से प्रत्येक धागे एक ही आवेदन के हैं। इसका मतलब है कि आप स्थिर के रूप में चिह्नित कुछ भी सभी अनुरोधों में साझा किया जाता है, और इसलिए सभी सत्र और उपयोगकर्ता भी।

इस मामले में, MyFunc समारोह है कि आपके पेज वर्ग का हिस्सा हर page_init साथ A में स्थिर Func सदस्य के शीर्ष पर कॉपी किया जाता है, और इसलिए हर बार किसी भी उपयोगकर्ता है एक page_init, वह है जगह A.Func द्वारा प्रयोग किया जाता सभी अनुरोध।

+0

मुझे समझ में आता है कि फ़ंक्शन पता बदल दिया जा रहा है। मुझे समझ में नहीं आता है, हालांकि, फ़ंक्शन में डेटा का उपयोग क्यों किया जा रहा है। सत्र # 1 क्यों है, जिसमें सत्र है। सत्र आईडी = abababababab, जब myFunc को फिर से कॉल करते हैं, तो अचानक सत्र होता है। SessionID = cdcdcdcdcdcd? –

+0

क्योंकि प्रतिनिधि उस विधि के पूरे वातावरण को कैप्चर करता है, जिसमें वर्तमान सत्र ऑब्जेक्ट भी शामिल है जब आप इसे स्थिर प्रतिनिधि को सौंप देते हैं। – nos

+0

क्योंकि सत्र # 1 से पहले Q() कन्स्ट्रक्टर सत्र सत्र # 2 में स्थिर A.Func() विधि को कॉल किया गया है, उस फ़ंक्शन को अपने स्वयं के कार्यान्वयन के साथ बदल दिया गया है। आप दूसरी बार दौर में एक पूरी तरह से अलग समारोह बुला रहे हैं। –

4

स्टेटिक डेटा अपने वेब ऐप्लिकेशन की पूरी application domain के बीच साझा किया जाता है। संक्षेप में, यह आपके वेबपैप में अनुरोध करने वाले सभी थ्रेडों के बीच साझा किया गया है, यह किसी भी तरह से सत्र/थ्रेड/उपयोगकर्ता से पूरी तरह से वेबपैप तक नहीं है। (उदाहरण के लिए php जहां प्रत्येक अनुरोध अपने अलग वातावरण में रहता है बार में कुछ घुंडी प्रदान की -। इस तरह के सत्र चर के रूप में)

+0

जैसा कि मैं जोएल को अपनी टिप्पणी में ठीक से क्रियान्वित करने की कोशिश कर रहा हूं, मुझे समझ में आता है कि फ़ंक्शन संदर्भ ऐप डोमेन के बीच क्यों साझा किया जाता है। मुझे समझ में नहीं आता कि वेरिएबल्स जो फ़ंक्शन के तर्क के भीतर स्थित सत्र/थ्रेड/उपयोगकर्ता हैं, वे भी एप्लिकेशन डोमेन के बीच साझा किए जा रहे हैं। –

4

मैं स्थिर सदस्यों के अन्य उत्तर 'स्पष्टीकरण पर सुधार करने की कोशिश नहीं करेंगे, लेकिन अपने तत्काल समस्या को हल कोड करने के लिए एक और तरीका है बाहर बिंदु करना चाहते हैं।

एक समाधान के रूप में, आप अपने वर्ग A का एक उदाहरण उन्मुख संस्करण बनाने के एक पृष्ठ-स्तरीय चर में संग्रहीत है, और Q के निर्माता के लिए यह पृष्ठ लोड पर दे सकते हैं:

public class MyPage: Page { 
    private A2 _a2; 

    // I've modified A2's constructor here to accept the function 
    protected Page_Init() { this._a2 = new A2(MyFunc); } 

    protected Page_Load() { 
     Q myQ = new Q(this._a2); 
     // etc.. 
    } 
} 

में तथ्य, अगर A2 पहले घोषित करने की कोई दिक्कत नहीं है, तो आप Page_Load में Q का अपना उदाहरण बनाते समय इसे तुरंत चालू कर सकते हैं।

संपादित करें: अन्य टिप्पणियों में उठाए गए प्रश्न का उत्तर देने के लिए, चर को साझा करने का कारण यह है कि अनुरोध एक ही प्रतिनिधि को साझा कर रहे हैं, जिसमें इसकी चर की केवल एक प्रति है। अधिक जानकारी के लिए जॉन स्कीट के The Beauty of Closures देखें।

+0

DOH !!!!!!! यह अब मुझे पूरी समझ में आता है। मुझे यह भी एहसास नहीं हुआ कि मैंने इस मामले में बंद कर दिया है। मेरा उदाहरण कोड असली कोड का एक बेहद सरलीकृत संस्करण है - दुर्भाग्यवश, आपका प्रस्तावित समाधान वास्तविक मामले में फिट नहीं होगा। लेकिन बंद स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। –

1

आप वर्तमान अनुरोध के लिए केवल लागू करने के लिए डेटा चाहते हैं, HttpContext.Items का उपयोग करें: http://msdn.microsoft.com/en-us/library/system.web.httpcontext.items.aspx

आप डेटा वर्तमान उपयोगकर्ता के सत्र के लिए बनाए रखना चाहते हैं (यह मानते हुए आप सत्र स्थिति सक्षम किया गया है), HttpContext.Session का उपयोग करें: http://msdn.microsoft.com/en-us/library/system.web.httpcontext.session.aspx

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