अनुरोध में स्थिर वर्ग उदाहरण या ASP.NET में एक सर्वर है?


182

ASP.NET वेबसाइट पर, स्थिर वर्ग प्रत्येक वेब अनुरोध के लिए विशिष्ट होते हैं, या जब भी जरूरत होती है और जब भी जीसी उनका निस्तारण करता है, तो जब भी जरूरत पड़ती है, तो क्या वे त्वरित होते हैं?

मेरे द्वारा पूछे जाने का कारण यह है क्योंकि मैंने C # से पहले कुछ स्थिर कक्षाएं लिखी हैं और व्यवहार मेरे द्वारा अपेक्षा से अलग है। मैंने स्टैटिक क्लासेस से प्रत्येक अनुरोध के लिए अद्वितीय होने की उम्मीद की होगी, लेकिन ऐसा नहीं लगता कि ऐसा ही है।

यदि वे प्रत्येक अनुरोध के लिए अद्वितीय नहीं हैं, तो क्या उन्हें अनुमति देने का कोई तरीका है?

अद्यतन:
उत्तर सूक्तियों ने मुझे वही दिया जिसकी मुझे आवश्यकता थी। मैं पहले से ही एक सिंगलटन वर्ग का उपयोग कर रहा था, हालांकि यह एक स्थिर उदाहरण का उपयोग कर रहा था और इसलिए अनुरोधों के बीच साझा किया जा रहा था, भले ही उपयोगकर्ता अलग थे जो इस मामले में एक बुरी बात थी। का उपयोग करते हुए HttpContext.Current.Itemsहल मेरी समस्या पूरी तरह से। भविष्य में इस सवाल पर ठोकर खाने वाले के लिए, यहाँ मेरा कार्यान्वयन, सरलीकृत और छोटा किया गया है ताकि पैटर्न को समझना आसान हो:

using System.Collections;
using System.Web;

public class GloballyAccessibleClass
{
    private GloballyAccessibleClass() { }

    public static GloballyAccessibleClass Instance
    {
        get
        {
            IDictionary items = HttpContext.Current.Items;
            if(!items.Contains("TheInstance"))
            {
                items["TheInstance"] = new GloballyAccessibleClass();
            }
            return items["TheInstance"] as GloballyAccessibleClass;
        }
    }
}

बस एक सिर: यदि आप अपने अनुरोध को पुनर्निर्देशित करते हैं, तो कहें, filterContext.Result = new RedirectResult(...)आप के साथ अपने आइटम खो देंगे क्योंकि एक नया HttpContext बनाया जाएगा। यहाँ अधिक जानकारी: stackoverflow.com/questions/16697601/…
रिबेल रिबेरो

एक अच्छे उत्तर के साथ एक संबंधित प्रश्न stackoverflow.com/q/5219431 पर है
थियोफिलस

जवाबों:


146

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

यदि आपको अनुरोध के रूप में एक ही जीवनकाल के साथ एक उदाहरण की आवश्यकता है, तो मैं HttpContext.Current.Itemsसंग्रह का उपयोग करने का सुझाव दूंगा। यह डिज़ाइन के लिए सामान रखने के लिए एक जगह है जिसका आपको अनुरोध करने की आवश्यकता है। अच्छे डिजाइन और पठनीयता के लिए, आप इन वस्तुओं का प्रबंधन करने में मदद करने के लिए सिंगलटन पैटर्न का उपयोग कर सकते हैं। बस एक सिंगलटन वर्ग बनाएं जो अपने उदाहरण को इसमें संग्रहीत करता है HttpContext.Current.Items। (ASP.NET के लिए मेरी सामान्य लाइब्रेरी में, मेरे पास इस उद्देश्य के लिए एक सामान्य सिंगलटनरैक्स्ट क्लास है)।


3
क्या आप अपने सिंगलटन पैटर्न का एक नमूना प्रदान कर सकते हैं HttpContext.Current.Items?
Airn5475

मेरी स्थिति के बारे में अधिक जानकारी: मेरे वेब ऐप में, उपयोगकर्ता कोड के एक वर्ग पुस्तकालय के माध्यम से चलेगा जो एक साझा वर्ग संपत्ति का उपयोग करता है। मैं चाहता हूं कि यह संपत्ति उपयोगकर्ता के लिए विशिष्ट हो, लेकिन मैं इस संपत्ति को विभिन्न कार्यों के लिए सौंपना नहीं चाहता। क्या आपके द्वारा उल्लेखित डिजाइन, इसे ठीक से संभाल सकता है?
Airn5475

कृपया, क्या आप सिंगलटनरैक्स्ट क्लास को साझा कर सकते हैं?
तेबो

मैं किसी भी डेटा को स्टैटिक क्लास में स्टोर नहीं करता। मैं डेटा प्राप्त करने या डेटा लेयर के रूप में डेटा सेट करने के लिए केवल स्थिर वर्ग का उपयोग करता हूं। तो क्या कोई समस्या है?
भड़कीले

"static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed"- क्या इसके लिए कोई स्रोत है, क्योंकि मैंने जो कुछ भी पढ़ा है उसके साथ कोई मतलब नहीं है और संघर्ष नहीं करता है। जब AppPool को रीसायकल किया जाता है तो संबंधित ऐप डोमेन पूरी तरह से फट जाता है और GC'd। जब ऐसा होता है तो कोई भी संबंधित स्थैतिक उदाहरण GC'd भी होगा क्योंकि उनकी जड़ (AppDomain) चली गई है। पूल के एक हिस्से के रूप में एक नया AppDomain बनाया गया है और यह स्थिर उदाहरणों से जुड़ा हुआ है।
निक

30

स्थैतिक सदस्यों के पास केवल वर्तमान कार्यकर्ता प्रक्रिया का एक दायरा होता है, इसलिए इसका अनुरोधों से कोई लेना-देना नहीं है, क्योंकि विभिन्न अनुरोधों को एक ही कार्यकर्ता प्रक्रिया द्वारा नियंत्रित किया जा सकता है या नहीं किया जा सकता है।

  • किसी विशिष्ट उपयोगकर्ता और अनुरोधों के साथ डेटा साझा करने के लिए, HttpContext.Current.Session का उपयोग करें।
  • किसी विशिष्ट अनुरोध के भीतर डेटा साझा करने के लिए, HttpContext.Current.Items का उपयोग करें।
  • संपूर्ण एप्लिकेशन में डेटा साझा करने के लिए, या तो इसके लिए एक तंत्र लिखें, या एक एकल प्रक्रिया के साथ काम करने के लिए IIS को कॉन्फ़िगर करें और एक सिंगलटन / उपयोग एप्लिकेशन लिखें।

वैसे, कार्यकर्ता प्रक्रियाओं की डिफ़ॉल्ट संख्या 1 है, इसलिए यही कारण है कि वेब यह सोचकर भरा हुआ है कि स्थिर सदस्यों के पास पूरे आवेदन का एक क्षेत्र है।


11

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

मैं वस्तुओं को किसी विशेष अनुरोध के लिए विशिष्ट बनाने के कई तरीकों के बारे में सोच सकता हूं जो आप करना चाहते हैं, इस पर निर्भर करता है। उदाहरण के लिए आप ऑब्जेक्ट को Application.BeginRequest में झटपट कर सकते हैं और फिर इसे HttpRequest ऑब्जेक्ट में संग्रहीत कर सकते हैं ताकि इसे सभी वस्तुओं तक पहुँचा जा सके। अनुरोध प्रसंस्करण पाइप लाइन।


4

यदि वे प्रत्येक अनुरोध के लिए अद्वितीय नहीं हैं, तो क्या उन्हें अनुमति देने का कोई तरीका है?

नहीं। स्थैतिक सदस्य ASP.NET प्रक्रिया के स्वामित्व में हैं और वेब ऐप के सभी उपयोगकर्ताओं द्वारा साझा किए जाते हैं । आपको अन्य सत्र प्रबंधन तकनीकों जैसे सत्र चर को चालू करने की आवश्यकता होगी।


1

आम तौर पर स्थिर तरीके, गुण और वर्ग Applicationस्तर पर सामान्य होते हैं । जब तक आवेदन रहता है, वे साझा किए जाते हैं।

आप ThreadStaticविशेषता का उपयोग करके एक अलग व्यवहार निर्दिष्ट कर सकते हैं । उस स्थिति में वे वर्तमान धागे के लिए विशिष्ट होंगे, जो मुझे लगता है कि प्रत्येक अनुरोध के लिए विशिष्ट है।
मैं इसे सलाह नहीं दूंगा हालांकि यह अधूरा लगता है।

आप HttpContext.Current.Itemsएक अनुरोध के लिए सामान सेट करने के लिए उपयोग कर सकते हैं , या HttpContext.Current.Sessionएक उपयोगकर्ता के लिए सामान सेट करने के लिए (अनुरोधों के पार)।

सामान्य तौर पर, जब तक कि आपको चीजों का उपयोग नहीं करना है, तब तक Server.Transferसबसे अच्छा तरीका मूल रूप से एक बार चीजें बनाना और फिर उन्हें विधि आह्वान के माध्यम से स्पष्ट रूप से पारित करना है।


3
जॉन स्कीट हमें पता चलता है कि ThreadStatic में सुरक्षित नहीं है ASP.Net stackoverflow.com/questions/4791208/...
मार्क Lindell

डाउन-वोटिंग चूंकि एक अनुरोध के लिए एक धागा अद्वितीय नहीं है। कृपया, इस उत्तर को हटा दें
Seebiscuit
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.