उच्च ट्रैफ़िक परिदृश्य में ASP.NET में ThreadPool.QueueUserWorkItem का उपयोग करना


111

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

तो यहाँ बताया गया है कि मैं अब तक कैसे छोटे-छोटे अतुल्यकालिक कार्य कर रहा हूँ:

ThreadPool.QueueUserWorkItem(s => PostLog(logEvent))

और लेख इसके बजाय स्पष्ट रूप से एक धागा बनाने के लिए सुझाव दे रहा है:

new Thread(() => PostLog(logEvent)){ IsBackground = true }.Start()

पहली विधि में प्रबंधित और बंधे होने का लाभ है, लेकिन इसमें वह क्षमता है (यदि लेख सही है) कि पृष्ठभूमि कार्य तब ASP.NET अनुरोध-हैंडलर के साथ थ्रेड के लिए मर रहे हैं। दूसरी विधि थ्रेडपूल को मुक्त कर देती है, लेकिन अनबाउंड होने की कीमत पर और इस प्रकार संभवतः कई संसाधनों का उपयोग कर।

तो मेरा सवाल है, क्या लेख में सलाह सही है?

यदि आपकी साइट पर इतना अधिक ट्रैफ़िक आ रहा है कि आपका थ्रेडपूल भरा हुआ है, तो क्या बाहर जाना बेहतर है, या फ़ुल थ्रेडपूल का अर्थ यह होगा कि आप अपने संसाधनों की सीमा तक वैसे भी पहुँच रहे हैं, जिस स्थिति में आप अपने खुद के धागे शुरू करने की कोशिश नहीं करनी चाहिए?

स्पष्टता: मैं सिर्फ छोटे गैर-महत्वपूर्ण अतुल्यकालिक कार्यों (जैसे, रिमोट लॉगिंग) के दायरे में पूछ रहा हूं, न कि महंगी काम की वस्तुओं के लिए एक अलग प्रक्रिया की आवश्यकता होती है (इन मामलों में मैं मानता हूं कि आपको अधिक मजबूत समाधान की आवश्यकता होगी)।


कथानक गाढ़ा होता है - मुझे यह लेख ( blogs.msdn.com/nicd/archive/2007/04/16/… ) मिला, जिसे मैं काफी डिकोड नहीं कर सकता। एक तरफ, यह कहा जा रहा है कि IIS 6.0+ हमेशा थ्रेड पूल वर्कर थ्रेड्स पर अनुरोधों की प्रक्रिया करता है (और पहले के संस्करण ऐसा कर सकते हैं), लेकिन फिर यह है: "हालाँकि यदि आप नए .NET 2.0 async पेजों का उपयोग कर रहे हैं ( Async = "true") या ThreadPool.QueueUserWorkItem (), फिर प्रोसेसिंग का अतुल्यकालिक भाग [एक पूर्ण पोर्ट थ्रेड] के अंदर किया जाएगा। " प्रसंस्करण का अतुल्यकालिक हिस्सा ?
जेफ सनातन

एक अन्य बात - यह IIS 6.0+ इंस्टॉलेशन (जो अभी मेरे पास नहीं है) पर परीक्षण करने के लिए पर्याप्त आसान होना चाहिए, यह जांचने से कि क्या थ्रेड पूल के उपलब्ध वर्कर थ्रेड्स अपने अधिकतम वर्कर थ्रेड्स से कम है, तो कतार के भीतर भी ऐसा ही करें। कार्य वस्तुएं।
जेफ सनातन

जवाबों:


104

यहाँ अन्य उत्तर सबसे महत्वपूर्ण बिंदु को छोड़ते हुए प्रतीत होते हैं:

जब तक आप कम-लोड साइट पर तेजी से काम करने के लिए सीपीयू-गहन ऑपरेशन को समानांतर करने की कोशिश कर रहे हैं, तब तक श्रमिक थ्रेड का उपयोग करने का कोई मतलब नहीं है।

अनुरोधों के जवाब new Thread(...)में दोनों मुक्त धागे, द्वारा बनाए गए , और कार्यकर्ता धागे के ThreadPoolलिए जाते QueueUserWorkItemहैं।

हां, यह सच है, आप ASP.NET प्रक्रिया में बहुत अधिक काम की वस्तुओं की कतार लगाकर भूखे रह सकते हैंThreadPool । यह ASP.NET को आगे के अनुरोधों को संसाधित करने से रोकेगा। लेख की जानकारी उस संबंध में सटीक है; QueueUserWorkItemअनुरोधों की सेवा के लिए उपयोग किए जाने वाले समान थ्रेड पूल का भी उपयोग किया जाता है।

लेकिन अगर आप वास्तव में इस भुखमरी का कारण बनने के लिए पर्याप्त कार्य वस्तुओं की कतार लगा रहे हैं, तो आपको थ्रेड पूल को भूखा रखना चाहिए! यदि आप एक ही समय में सैकड़ों सीपीयू-सघन संचालन कर रहे हैं, तो ASP.NET अनुरोध पर काम करने के लिए एक और श्रमिक धागा रखने से क्या अच्छा होगा, जब मशीन पहले से ही ओवरलोड हो? यदि आप इस स्थिति में चल रहे हैं, तो आपको पूरी तरह से नया स्वरूप देने की आवश्यकता है!

अधिकांश समय मैं बहु-थ्रेडेड कोड के बारे में ASP.NET में अनुचित रूप से उपयोग किए जाने के बारे में देखता या सुनता हूं, यह सीपीयू-गहन कार्य को कतारबद्ध करने के लिए नहीं है। यह कतारबद्ध I / O- बाउंड कार्य के लिए है। और यदि आप I / O कार्य करना चाहते हैं, तो आपको I / O थ्रेड (I / O पूर्णता पोर्ट) का उपयोग करना चाहिए।

विशेष रूप से, आप जो भी पुस्तकालय वर्ग का उपयोग कर रहे हैं, उसके द्वारा समर्थित async कॉलबैक का उपयोग करना चाहिए। इन विधियों को हमेशा बहुत स्पष्ट रूप से लेबल किया जाता है; वे शब्दों के साथ शुरू करते हैं Beginऔर End। के रूप में Stream.BeginRead, Socket.BeginConnectमें WebRequest.BeginGetResponse, और इतने पर।

इन विधियों करना का उपयोग करें ThreadPool, लेकिन वे IOCPs, जो है का उपयोग नहीं ASP.NET अनुरोध के साथ हस्तक्षेप। वे एक विशेष प्रकार के हल्के धागे हैं जो I / O सिस्टम से एक बाधा संकेत द्वारा "जागने" हो सकते हैं। और एक ASP.NET अनुप्रयोग में, आपके पास सामान्य रूप से प्रत्येक कार्यकर्ता थ्रेड के लिए एक I / O थ्रेड होता है, इसलिए हर एक अनुरोध में एक async ऑपरेशन हो सकता है। वस्तुतः बिना किसी महत्वपूर्ण प्रदर्शन में गिरावट के सैकड़ों async ऑपरेशंस हैं (I / O सबसिस्टम रख सकते हैं)। यह कभी भी आप की आवश्यकता से अधिक है।

बस ध्यान रखें कि async डेलीगेट्स इस तरह से काम नहीं करते हैं - वे मजदूर धागे का उपयोग करके समाप्त करेंगे, ठीक उसी तरह ThreadPool.QueueUserWorkItem। यह केवल .NET फ्रेमवर्क लाइब्रेरी क्लासेज का बिल्ट-इन एसिंक्स मेथड है जो ऐसा करने में सक्षम हैं। आप इसे स्वयं कर सकते हैं, लेकिन यह जटिल और थोड़ा खतरनाक है और शायद इस चर्चा के दायरे से परे है।

इस सवाल का सर्वश्रेष्ठ उत्तर, मेरी राय में, है का उपयोग नहीं करते ThreadPool या एक पृष्ठभूमि Threadउदाहरण ASP.NET में । यह विंडोज फॉर्म एप्लीकेशन में एक धागे को पिरोने जैसा बिल्कुल भी नहीं है, जहां आप यूआई को रिस्पांसिबल रखने के लिए ऐसा करते हैं और इस बात की परवाह नहीं करते कि यह कितना कारगर है। ASP.NET में, आपकी चिंता थ्रूपुट है , और उन सभी वर्कर थ्रेड्स पर स्विच करने वाले सभी संदर्भ आपके थ्रूपुट को मारने जा रहे हैं, चाहे आप इसका उपयोग करें ThreadPoolया नहीं।

कृपया, यदि आप खुद को ASP.NET में थ्रेडिंग कोड लिखते हुए पाते हैं - विचार करें कि क्या यह पहले से मौजूद अतुल्यकालिक विधियों का उपयोग करने के लिए फिर से लिखा जा सकता है या नहीं, और यदि यह नहीं हो सकता है, तो कृपया विचार करें कि क्या आपको वास्तव में कोड की आवश्यकता है या नहीं एक पृष्ठभूमि थ्रेड में चलाने के लिए। अधिकांश मामलों में, आप शायद शुद्ध लाभ के लिए जटिलता जोड़ रहे हैं।


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

@ मिचेल: यदि आप इसे और अधिक स्तर तक धकेलना चाहते हैं, तो Async कॉलबैक को लपेटना बहुत आसान है; आप async विधियों के चारों ओर एक मुखौटा बना सकते हैं और उन्हें एक एकल विधि के साथ लपेट सकते हैं जो Action<T>उदाहरण के लिए कॉलबैक के रूप में उपयोग करता है । यदि आप का मतलब है कि कार्यकर्ता धागा या I / O धागा का उपयोग करने का विकल्प न्यूनतम स्तर पर होता है, तो यह जानबूझकर होता है; केवल वह स्तर तय कर सकता है कि उसे IOCP की आवश्यकता है या नहीं।
हारून

हालाँकि, रुचि के बिंदु के रूप में, यह केवल .NET है ThreadPoolजो आपको इस तरह से सीमित करता है, शायद इसलिए कि वे डेवलपर्स को इसे प्राप्त करने के लिए विश्वास नहीं करते थे। अप्रबंधित विंडोज थ्रेड पूल में एक समान एपीआई है लेकिन वास्तव में आपको थ्रेड प्रकार का चयन करने की अनुमति देता है।
आरोहण

2
I / O पूर्णता पोर्ट (IOCP)। IOCP का वर्णन काफी सही नहीं है। IOCP में, आपके पास वर्कर थ्रेड्स की एक स्थिर संख्या होती है, जो सभी लंबित कार्यों पर काम करता है। थ्रेड पूल के साथ भ्रमित न होने के लिए जो आकार में तय या गतिशील हो सकते हैं लेकिन बीयू में प्रति कार्य एक धागा होता है - भयानक रूप से तराजू। ASYNC के विपरीत, आपके पास प्रति कार्य एक धागा नहीं है। IOCP थ्रेड कार्य 1 पर थोड़ा काम कर सकता है, फिर कार्य 3, कार्य 2 पर वापस फिर से कार्य 1 पर वापस आ सकता है। कार्य सत्र राज्य सहेजे जाते हैं और थ्रेड्स के बीच पारित किए जाते हैं।
मिक्यड

1
डेटाबेस आवेषण के बारे में क्या? क्या कोई ASYNC SQL कमांड (जैसे निष्पादित) है? डेटाबेस आवेषण सबसे धीमे I / O ऑपरेशन के बारे में होते हैं (लॉकिंग के कारण) और मुख्य थ्रेड पंक्ति (s) सम्मिलित होने की प्रतीक्षा करते हैं, बस CPU चक्रों की बर्बादी होती है।
इयान थॉम्पसन

45

Microsoft में ASP.NET टीम के थॉमस मारक्वाड प्रति ASP.NET थ्रेडपूल (QueueUserWorkItem) का उपयोग करना सुरक्षित है।

लेख से :

प्र) यदि मेरा ASP.NET अनुप्रयोग CLR थ्रेडपूल थ्रेड्स का उपयोग करता है, तो क्या मैं ASP.NET को भूखा नहीं रखूंगा, जो अनुरोधों को निष्पादित करने के लिए CLR थ्रेडपूल का उपयोग करता है? ..

क) संक्षेप में, धागे के ASP.NET भूखे होने के बारे में चिंता न करें, और यदि आपको लगता है कि यहाँ कोई समस्या है तो मुझे बताएं और हम इसका ध्यान रखेंगे।

प्र) क्या मुझे अपने स्वयं के धागे (नए धागे) बनाने चाहिए? यह ASP.NET के लिए बेहतर नहीं होगा, क्योंकि यह CLR थ्रेडपूल का उपयोग करता है।

ए) कृपया मत करो। या इसे अलग तरीके से रखने के लिए, नहीं !!! यदि आप मुझसे बहुत ज्यादा स्मार्ट हैं - तो आप अपने खुद के धागे बना सकते हैं; अन्यथा, इसके बारे में भी मत सोचो। यहां कुछ कारण बताए गए हैं कि आपको अक्सर नए धागे क्यों नहीं बनाने चाहिए:

  1. यह QueueUserWorkItem की तुलना में बहुत महंगा है ... वैसे, यदि आप CLR की तुलना में बेहतर थ्रेडपूल लिख सकते हैं, तो मैं आपको Microsoft में नौकरी के लिए आवेदन करने के लिए प्रोत्साहित करता हूं, क्योंकि हम निश्चित रूप से आप जैसे लोगों की तलाश कर रहे हैं।

4

वेबसाइटों को थ्रेडिंग के आसपास नहीं जाना चाहिए।

आप आमतौर पर इस कार्यक्षमता को विंडोज सेवा में स्थानांतरित करते हैं जिसे आप तब संवाद करते हैं (मैं उनसे बात करने के लिए एमएसएमक्यू का उपयोग करता हूं)।

- संपादित करें

मैंने यहाँ एक कार्यान्वयन का वर्णन किया: ASP.NET MVC वेब अनुप्रयोग में कतार-आधारित पृष्ठभूमि प्रसंस्करण

- संपादित करें

यह विस्तार करने के लिए कि यह केवल थ्रेड्स से बेहतर क्यों है:

MSMQ का उपयोग करके, आप किसी अन्य सर्वर से संवाद कर सकते हैं। आप मशीनों के पार एक कतार में लिख सकते हैं, इसलिए यदि आप किसी कारण से निर्धारित करते हैं, कि आपका पृष्ठभूमि कार्य मुख्य सर्वर के संसाधनों का बहुत अधिक उपयोग कर रहा है, तो आप इसे काफी तुच्छ तरीके से स्थानांतरित कर सकते हैं।

यह आपको बैच-प्रोसेस करने की भी अनुमति देता है जो भी कार्य आप करने की कोशिश कर रहे थे (ईमेल / जो भी भेजें)।


4
मैं इस बात से सहमत नहीं हूँ कि यह कंबल कथन हमेशा सत्य है - विशेष रूप से गैर-महत्वपूर्ण कार्यों के लिए। विंडोज सर्विस बनाना, अतुल्यकालिक लॉगिंग के प्रयोजनों के लिए निश्चित रूप से ओवरकिल लगता है। इसके अलावा, वह विकल्प हमेशा उपलब्ध नहीं होता है (एमएसएमक्यू और / या विंडोज सेवा को तैनात करने में सक्षम)।
माइकल हार्ट

ज़रूर, लेकिन यह एक वेबसाइट से अतुल्यकालिक कार्यों को लागू करने का 'मानक' तरीका है (किसी अन्य प्रक्रिया के खिलाफ कतार विषय)।
दोपहर सिल्क

2
सभी अतुल्यकालिक कार्यों को समान नहीं बनाया गया है, यही कारण है कि उदाहरण के लिए ASP.NET पृष्ठों में ASP.NET मौजूद है। यदि मैं किसी दूरस्थ वेब सेवा से परिणाम प्राप्त करना चाहता हूं, तो मैं MSMQ के माध्यम से ऐसा नहीं करने जा रहा हूं। इस मामले में, मैं दूरस्थ पोस्ट का उपयोग करके लॉग को लिख रहा हूं। यह एक विंडोज सेवा लिखने के लिए समस्या को फिट नहीं करता है, और न ही इसके लिए MSMQ को हुक करता है (और न ही मैं कर सकता हूं क्योंकि यह विशेष एप्लिकेशन अज़ान पर है)।
माइकल हार्ट

1
गौर कीजिए: आप एक दूरस्थ होस्ट को लिख रहे हैं? क्या होगा अगर वह होस्ट डाउन हो या अन-रीचेबल हो? क्या आप अपने लेखन को फिर से आज़माना चाहेंगे? शायद आप करेंगे, शायद आप नहीं करेंगे। आपके कार्यान्वयन के साथ, यह फिर से प्रयास करना मुश्किल है। सेवा के साथ, यह काफी तुच्छ हो जाता है। मैं सराहना करता हूं कि आप इसे करने में सक्षम नहीं हो सकते हैं, और मैं किसी और को वेबसाइटों से धागे बनाने के साथ विशिष्ट समस्याओं का जवाब दूंगा [अर्थात यदि आपका धागा पृष्ठभूमि नहीं था, आदि], लेकिन मैं 'उचित' की रूपरेखा तैयार कर रहा हूं। इसे करने का तरीका। मैं azure से परिचित नहीं हूँ, हालाँकि मैंने ec2 का उपयोग किया है (आप उस पर OS स्थापित कर सकते हैं, इसलिए कुछ भी ठीक है)।
दोपहर

@silky, टिप्पणियों के लिए धन्यवाद। मैंने इस अधिक हैवीवेट (अभी तक टिकाऊ) समाधान से बचने के लिए "गैर-महत्वपूर्ण" कहा था। मैंने प्रश्न को स्पष्ट कर दिया है ताकि यह स्पष्ट हो कि मैं कतारबद्ध काम की वस्तुओं के आसपास सर्वोत्तम अभ्यास के लिए नहीं कह रहा हूं। Azure इस प्रकार के परिदृश्य का समर्थन करता है (इसकी अपनी कतार संग्रहण है) - लेकिन तुल्यकालिक लॉगिंग के लिए कतार संचालन बहुत महंगा है, इसलिए मुझे वैसे भी एक अतुल्यकालिक समाधान की आवश्यकता होगी। मेरे मामले में मुझे विफलता के नुकसान के बारे में पता है, लेकिन इस विशेष लॉगिंग प्रदाता के विफल होने की स्थिति में मैं अधिक बुनियादी ढांचा नहीं जोड़ने जा रहा हूं - मुझे अन्य लॉगिंग प्रदाता भी मिल गए हैं।
माइकल हार्ट

4

मुझे निश्चित रूप से लगता है कि ASP.NET में त्वरित, कम-प्राथमिकता वाले अतुल्यकालिक काम के लिए सामान्य अभ्यास .NET थ्रेड पूल का उपयोग करना होगा, विशेष रूप से उच्च-यातायात परिदृश्यों के लिए जैसा कि आप चाहते हैं कि आपके संसाधन बाध्य हों।

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

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

यदि आपके पास प्रदर्शन की समस्या नहीं है, तो ASP.NET अनुरोध कतार के साथ विवाद को कम करने के लिए नए थ्रेड्स चुनने के लिए क्लासिक प्रीमेच्योर ऑप्टिमाइज़ेशन है।

आदर्श रूप से आपको लॉगिंग ऑपरेशन करने के लिए एक अलग थ्रेड का उपयोग करने की आवश्यकता नहीं होगी - बस मूल थ्रेड को ऑपरेशन को जल्दी से जल्दी पूरा करने में सक्षम बनाता है, जहां MSMQ और एक अलग उपभोक्ता थ्रेड / प्रक्रिया तस्वीर में आती है। मैं मानता हूं कि यह लागू करने के लिए भारी और अधिक काम है, लेकिन आपको वास्तव में यहां स्थायित्व की आवश्यकता है - एक साझा, इन-मेमोरी कतार की अस्थिरता जल्दी से अपना स्वागत करेगी।


2

आपको QueueUserWorkItem का उपयोग करना चाहिए, और नए धागे बनाने से बचें जैसे आप प्लेग से बचेंगे। एक दृश्य के लिए जो बताता है कि आप ASP.NET को क्यों नहीं देखेंगे, क्योंकि यह एक ही थ्रेडपूल का उपयोग करता है, आधा दर्जन बॉलिंग पिन, तलवार या फ्लाइट में जो भी हो, रखने के लिए दो हाथों का उपयोग करके बहुत कुशल बाजीगर की कल्पना करें। अपने स्वयं के धागों को बनाने के दृश्य के लिए बुरा है, कल्पना कीजिए कि सिएटल में घंटो में क्या होता है जब राजमार्ग के लिए भारी उपयोग किए जाने वाले प्रवेश द्वार रैंप पर वाहनों को प्रकाश का उपयोग करने के बजाय तुरंत प्रवेश करने की अनुमति देते हैं और हर कुछ सेकंड में प्रवेश द्वार की संख्या को सीमित करते हैं। । अंत में, एक विस्तृत विवरण के लिए, कृपया इस लिंक को देखें:

http://blogs.msdn.com/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx

धन्यवाद, थॉमस


यह लिंक बहुत उपयोगी है, उस थॉमस के लिए धन्यवाद। मुझे यह सुनने में रुचि होगी कि आप @ आरोन्यूज़ की प्रतिक्रिया के बारे में क्या सोचते हैं।
माइकल हार्ट

मैं हारून के साथ सहमत हूं, और अपने ब्लॉग पोस्ट में भी यही कहा। मैंने इसे इस तरह से रखा, "इस निर्णय को सरल बनाने के प्रयास में, आपको केवल [दूसरे धागे पर स्विच करना चाहिए] यदि आप अन्यथा ASP.NET अनुरोध थ्रेड को ब्लॉक कर देंगे, जबकि आप कुछ भी नहीं करते हैं। यह एक निगरानी है, लेकिन मैं कोशिश कर रहा हूं। निर्णय को सरल बनाने के लिए। ” दूसरे शब्दों में, इसे गैर-अवरुद्ध कम्प्यूटेशनल कार्य के लिए मत करो, लेकिन यदि आप किसी दूरस्थ सर्वर के लिए async वेब सेवा अनुरोध कर रहे हैं, तो इसे करें। सुनो हारून! :)
थॉमस

1

वह लेख सही नहीं है। ASP.NET अनुरोधों की सेवा के लिए ASP.NET के पास थ्रेड्स, प्रबंधित कार्यकर्ता थ्रेड्स का अपना पूल है। यह पूल आमतौर पर कुछ सौ धागे होते हैं और थ्रेडपूल पूल से अलग होते हैं, जो कुछ छोटे प्रोसेसर होते हैं।

ASP.NET में थ्रेडपूल का उपयोग करने से ASP.NET वर्कर थ्रेड्स के साथ हस्तक्षेप नहीं होगा। थ्रेडपूल का उपयोग करना ठीक है।

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

हर संदेश के लिए एक नए धागे का उपयोग निश्चित रूप से ओवरकिल है।

एक अन्य विकल्प, यदि आप केवल लॉगिंग के बारे में बात कर रहे हैं, तो लॉग 4नेट जैसी लाइब्रेरी का उपयोग करना है। यह एक अलग थ्रेड में लॉगिंग को हैंडल करता है और उस परिदृश्य में आने वाले सभी संदर्भ मुद्दों का ध्यान रखता है।


1
@Sam, मैं वास्तव में log4net का उपयोग कर रहा हूं और लॉग को अलग थ्रेड में नहीं देखा जा रहा है - क्या कुछ प्रकार का विकल्प है जिसे मुझे सक्षम करने की आवश्यकता है?
माइकल हार्ट

1

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

प्रति प्रक्रिया एक थ्रेड पूल है। थ्रेड पूल में उपलब्ध प्रोसेसर के प्रति 250 कार्यकर्ता थ्रेड्स का डिफ़ॉल्ट आकार है, और 1000 I / O पूरा होने वाले धागे हैं। थ्रेड पूल की थ्रेड्स की संख्या सेटमैक्सथ्रेड्स विधि का उपयोग करके बदली जा सकती है। प्रत्येक थ्रेड डिफ़ॉल्ट स्टैक आकार का उपयोग करता है और डिफ़ॉल्ट प्राथमिकता पर चलता है।


एक एकल प्रक्रिया में चल रहा एक आवेदन खुद को नीचे लाने में पूरी तरह से सक्षम है! (या कम से कम अपने स्वयं के प्रदर्शन को कम करने के लिए थ्रेड पूल को खोने का प्रस्ताव बनाने के लिए पर्याप्त है।)
जेफ सनातन

तो मैं अनुमान लगा रहा हूँ ASP.NET अनुरोध I / O पूर्ण थ्रेड्स का उपयोग करते हैं (जैसा कि वर्कर थ्रेड्स के विपरीत) - क्या यह सही है?
माइकल हार्ट

Fritz Onion के लेख से मैंने अपने उत्तर में लिंक किया: "यह प्रतिमान [IIS 5.0 से IIS 6.0 तक] जिस तरह से अनुरोधों को ASP.NET में संभाला जाता है। इसके बजाय inetinfo.exe से ASP.NET कार्यकर्ता प्रक्रिया, http पर अनुरोध भेजने के। sys सीधे प्रत्येक अनुरोध को उचित प्रक्रिया में कतार में लगाता है। इस प्रकार सभी अनुरोध अब CLR थ्रेड पूल से निकाले गए वर्कर थ्रेड्स द्वारा सेवित किए जाते हैं और I / O थ्रेड्स पर कभी नहीं । " (मेरा जोर)
जेफ सनातन

हम्म्म, मुझे अभी भी पूरी तरह से यकीन नहीं है ... यह लेख जून 2003 से है। यदि आप इसे मई 2004 से पढ़ते हैं (बेशक अभी भी काफी पुराना है), तो यह कहता है "स्लीप.स्पेक्स परीक्षण पृष्ठ का उपयोग एएसपी रखने के लिए किया जा सकता है। .NET I / O थ्रेड व्यस्त ", जहां Sleep.aspx केवल वर्तमान निष्पादित थ्रेड को सोने का कारण बनता है: msdn.microsoft.com/en-us/library/ms979194.aspx - जब मुझे मौका मिला है, तो मैं देखूंगा अगर मैं उस उदाहरण को कोड कर सकता हूं और IIS 7 और .NET 3.5 पर परीक्षण कर सकता हूं
माइकल हार्ट

हाँ, उस अनुच्छेद का पाठ भ्रामक है। उस सेक्शन में आगे यह एक सपोर्ट टॉपिक ( support.microsoft.com/default.aspx?scid=kb=EN-US-816829 ) से जुड़ता है, जो चीजों को स्पष्ट करता है: I / O पूरा होने पर थ्रेडिंग अनुरोध .NET .NET 1.0 था; समस्या जो ASP.NET 1.1 जून 2003 के हॉटफ़िक्स रोलअप पैकेज में तय की गई थी (जिसके बाद "सभी अनुरोध अब वर्कर थ्रेड पर चलते हैं")। इससे भी महत्वपूर्ण बात, यह उदाहरण काफी स्पष्ट रूप से दिखाता है कि ASP.NET थ्रेड पूल एक ही थ्रेड पूल है जिसे उजागर किया गया है System.Threading.ThreadPool
जेफ सनातन

1

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

  1. कुछ पेज के लिए एक अनुरोध किया जाता है
  2. Html को वापस परोसा जाता है
  3. Html क्लाइंट को आगे के जेटसेट (js, css, images आदि) बनाने के लिए कहता है।
  4. आगे की जानकारी वापस दी गई है

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

सैम यह भी सही है कि CLR पर थ्रेड पूल का उपयोग करने से IIS में थ्रेड पूल के साथ समस्या नहीं होगी। हालाँकि यहाँ ध्यान रखने वाली बात यह है कि आप एक प्रक्रिया से थ्रेडिंग नहीं कर रहे हैं, आप नए धागे IIS थ्रेडपूल थ्रेड्स से अलग कर रहे हैं। एक अंतर है और अंतर महत्वपूर्ण है।

प्रक्रिया बनाम सूत्र

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

इसके विपरीत, एक धागा एक कोडिंग निर्माण है जो किसी एप्लिकेशन की वास्तुकला को प्रभावित नहीं करता है। एक एकल प्रक्रिया में कई सूत्र हो सकते हैं; एक प्रक्रिया के भीतर सभी धागे एक ही राज्य और एक ही मेमोरी स्पेस साझा करते हैं, और एक दूसरे के साथ सीधे संवाद कर सकते हैं, क्योंकि वे एक ही चर साझा करते हैं।

स्रोत


3
@ धन्यवाद, इनपुट के लिए धन्यवाद, लेकिन मैं अच्छी तरह से जानता हूं कि एक वेब सर्वर कैसे काम करता है और यह वास्तव में सवाल के लिए प्रासंगिक नहीं है - फिर से, जैसा कि मैंने सवाल में कहा था, मैं इस पर एक वास्तुशिल्प के रूप में मार्गदर्शन नहीं मांग रहा हूं मुद्दा। मैं विशिष्ट तकनीकी जानकारी माँग रहा हूँ। जैसा कि इसके लिए "लकड़हारे की चिंता" होना चाहिए, जिसमें पहले से ही एक अतुल्यकालिक प्रक्रिया होनी चाहिए - आपको कैसे लगता है कि अतुल्यकालिक प्रक्रिया को लकड़हारा कार्यान्वयन द्वारा लिखा जाना चाहिए?
माइकल हार्ट

0

मैं संदर्भित लेख (C # feeds.com) से सहमत नहीं हूं। एक नया धागा बनाना आसान है लेकिन खतरनाक है। सिंगल कोर पर चलने के लिए सक्रिय थ्रेड्स की इष्टतम संख्या वास्तव में आश्चर्यजनक रूप से कम है - 10. से कम है। यह बहुत आसान है कि मशीन को थ्रेड स्विच करने में समय बर्बाद करने का कारण बन सकता है यदि थ्रेड्स को मामूली कार्यों के लिए बनाया जाता है। थ्रेड्स एक संसाधन है जो प्रबंधन की आवश्यकता है। इसे संभालने के लिए WorkItem अमूर्तता है।

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

अंत में लेख थ्रेडपूल का उपयोग करने के खतरों के बारे में कुछ सुंदर व्यापक बयान देता है, लेकिन यह वास्तव में उन्हें वापस करने के लिए कुछ ठोस करने की आवश्यकता है।


0

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

ऐसा लगता है कि एक उचित समझौता आपके ऐप के लिए एक एकल लॉगिंग थ्रेड आवंटित करने के लिए होगा जिसे आप संदेशों को पास कर सकते हैं। आप सावधान रहना चाहेंगे कि संदेश भेजना जितना संभव हो उतना तेज़ हो ताकि आप अपने ऐप को धीमा न करें।


0

आप Parallel.For या Parallel.ForEach का उपयोग कर सकते हैं और संभावित थ्रेड्स की सीमा को परिभाषित कर सकते हैं जिन्हें आप सुचारू रूप से चलाने और पूल भुखमरी को रोकने के लिए आवंटित करना चाहते हैं।

हालाँकि, पृष्ठभूमि में चलाया जा रहा है आपको ASP.Net वेब अनुप्रयोग में नीचे शुद्ध TPL शैली का उपयोग करना होगा।

var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;

ParallelOptions po = new ParallelOptions();
            po.CancellationToken = ts.Token;
            po.MaxDegreeOfParallelism = 6; //limit here

 Task.Factory.StartNew(()=>
                {                        
                  Parallel.ForEach(collectionList, po, (collectionItem) =>
                  {
                     //Code Here PostLog(logEvent);
                  }
                });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.