मुझे ASP.NET MVC में Async नियंत्रकों का उपयोग कब करना चाहिए?


216

मुझे ASP.NET MVC में async क्रियाओं का उपयोग करने में कुछ चिंताएँ हैं। जब यह मेरी क्षुधा के प्रदर्शन में सुधार होता है, और जब यह होता है ?

  1. क्या ASP.NET MVC में हर जगह async कार्रवाई का उपयोग करना अच्छा है?
  2. प्रतीक्षा करने योग्य तरीकों के बारे में: क्या मैं किसी डेटाबेस (EF / NHibernate / अन्य ORM के माध्यम से) को क्वेरी करना चाहता हूँ, तो मैं async / प्रतीक्षा कीवर्ड का उपयोग कर सकता हूँ?
  3. डेटाबेस में असमान रूप से एक सिंगल एक्शन विधि को क्वेरी करने के लिए मैं कितनी बार प्रतीक्षा कीवर्ड का उपयोग कर सकता हूं ?

जवाबों:


109

एसिंक्रोनस एक्शन तरीके उपयोगी होते हैं जब एक एक्शन को कई स्वतंत्र लंबे समय तक चलने वाले ऑपरेशनों को करना चाहिए।

AsyncController वर्ग के लिए एक विशिष्ट उपयोग लंबे समय से चलने वाली वेब सेवा कॉल है।

क्या मेरा डेटाबेस कॉल अतुल्यकालिक होना चाहिए?

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

आपको 1 और 2 संदर्भों पर एक नजर डालनी चाहिए

@PanagiotisKanavos टिप्पणियों से व्युत्पन्न:

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

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


27
Async, IIS और डेटाबेस के बारे में, ब्लॉग पोस्ट बहुत पुराना है और यहाँ निकाले गए निष्कर्ष गलत हैं। IIS को डेटाबेस की तुलना में बहुत अधिक भार सर्वर करना पड़ता है , थ्रेडपूल थ्रेड्स सीमित होते हैं और एक लंबी अनुरोध कतार 500 तक ले जा सकती है। जो कोई भी IO की प्रतीक्षा करते समय एक थ्रेड को मुक्त करता है, वह फायदेमंद होता है। यहां तक ​​कि लिंक भी नहीं हैं कि ओपी ने क्या पूछा। वास्तव में एक ही लेखक ने लिखा है कि आपको जहाँ कहीं भी अतुल्यकालिक DB विधियों का उपयोग करना चाहिए
Panagiotis Kanavos

30
इसके अलावा, async समानांतर मतलब नहीं है। अतुल्यकालिक निष्पादन बिना किसी जटिलता या प्रदर्शन लागत के एक बाहरी संसाधन के लिए अवरुद्ध होने से एक मूल्यवान थ्रेडपूल थ्रेड को मुक्त करता है। इसका मतलब है कि समान IIS मशीन अधिक समवर्ती अनुरोधों को संभाल सकती है , न कि यह तेजी से चलेगी।
पनगीओटीस कानावोस

5
आपको यह भी विचार करना चाहिए कि अवरुद्ध कॉल सीपीयू-गहन स्पिनवाइट के साथ शुरू होते हैं। तनाव के समय में, कॉल को अवरुद्ध करने से देरी और ऐप पूल रीसाइक्लिंग में परिणाम होगा। अतुल्यकालिक कॉल बस इससे बचते हैं
पैनागोटिस कानावोस

1
चूंकि यह स्वीकृत उत्तर है और इस प्रकार अधिकांश लोगों के लिए शीर्ष पर, निष्पादन के समय और समानांतर में चलने के संबंध में दूसरा पहला पैराग्राफ निकालने में समझदारी हो सकती है, जिसका async से कोई लेना-देना नहीं है। मैं वहाँ अंत में एक टिप्पणी है एहसास है, लेकिन यह है काफी भ्रामक।
रॉब

1
अतुल्यकालिक निष्पादन केवल उन मामलों में एक धागे को मुक्त करता है जब यह वास्तव में कार्यान्वयन के बहुत नीचे की ओर होता है और तैयारियों को इंगित करने के लिए और संदर्भ को बदलने और परिणाम को संसाधित करने के लिए नए थ्रेड को स्पिन करने के लिए कुछ कॉलबैक तंत्र का उपयोग करता है। इसलिए, मुझे यकीन नहीं है कि इस मामले में स्विचिंग / नए थ्रेड निर्माण केवल एक थ्रेड में परिणाम की प्रतीक्षा करने से अधिक कुशल है? लंबे समय से चलने वाली वेब सेवा कॉल वैसे भी एक बुरा विचार है, मैं इसे एक विश्वसनीय पृष्ठभूमि सेवा पर लोड करना पसंद करता हूं और क्लाइंट को परिणामों की जांच करने देता हूं, जो कुछ ही मिनटों, घंटों या दिनों में आ सकते हैं।
जस्टमार्टिन

229

आपको विषय पर मेरा MSDN लेख मददगार लग सकता है ; मैंने उस लेख में बहुत सी जगह ली, जिसमें यह वर्णन किया गया था कि आपकोasync ASP.NET पर उपयोग करना चाहिए , न किasync ASP.NET पर कैसे उपयोग किया जाए।

मुझे ASP.NET MVC में async क्रियाओं का उपयोग करने में कुछ चिंताएँ हैं। जब यह मेरे ऐप्स के प्रदर्शन में सुधार करता है, और जब - नहीं।

सबसे पहले, यह समझ async/ awaitसब के बारे में है धागे को मुक्त । जीयूआई अनुप्रयोगों पर, यह मुख्य रूप से जीयूआई थ्रेड को मुक्त करने के बारे में है ताकि उपयोगकर्ता अनुभव बेहतर हो। सर्वर अनुप्रयोगों पर (ASP.NET MVC सहित), यह मुख्य रूप से अनुरोध थ्रेड को मुक्त करने के बारे में है ताकि सर्वर स्केल कर सके।

विशेष रूप से, यह नहीं होगा:

  • अपने व्यक्तिगत अनुरोधों को तेज़ी से पूरा करें। वास्तव में, वे (बस एक किशोर सा) धीमी गति से पूरा करेंगे।
  • जब आप एक हिट करते हैं तो कॉल करने वाले / ब्राउज़र पर लौटें awaitawaitASP.NET थ्रेड पूल में केवल "पैदावार", ब्राउज़र के लिए नहीं।

पहला सवाल है - क्या एएसपीनेट एमवीसी में हर जगह एसिंक्स एक्शन का इस्तेमाल करना अच्छा है?

मैं कहूंगा कि आप इसका उपयोग हर उस जगह करना चाहते हैं जहाँ आप I / O कर रहे हैं। यह आवश्यक रूप से फायदेमंद नहीं हो सकता है , हालांकि (नीचे देखें)।

हालांकि, सीपीयू-बाउंड तरीकों के लिए इसका उपयोग करना बुरा है। कभी-कभी देवों को लगता है कि वे अपने नियंत्रकों में asyncकॉल करके लाभ प्राप्त कर सकते हैं Task.Run, और यह एक भयानक विचार है। क्योंकि वह कोड किसी अन्य धागे को लेने से अनुरोध थ्रेड को समाप्त कर देता है, इसलिए इसका कोई लाभ नहीं है (और वास्तव में, वे अतिरिक्त थ्रेड स्विच का दंड ले रहे हैं)!

जब मैं डेटाबेस (EF / NHibernate / अन्य ORM के माध्यम से) को क्वेरी करना चाहता हूँ, तो मैं async / प्रतीक्षारत खोजशब्दों का उपयोग करता हूँ?

आपके पास जो भी उपलब्ध विधियाँ हैं, उनका उपयोग आप कर सकते हैं। अभी अधिकांश प्रमुख खिलाड़ी समर्थन करते हैं async, लेकिन कुछ ऐसे हैं जो नहीं करते हैं। यदि आपका ORM समर्थन नहीं करता है async, तो इसे Task.Runया उस तरह की किसी चीज़ में लपेटने का प्रयास न करें (ऊपर देखें)।

ध्यान दें कि मैंने कहा "आप उपयोग कर सकते हैं"। यदि आप ASP.NET MVC के बारे में एकल डेटाबेस बैकएंड के साथ बात कर रहे हैं, तो आप (लगभग निश्चित रूप से) कोई स्केलेबिलिटी लाभ प्राप्त नहीं करने जा रहे हैं async। ऐसा इसलिए है क्योंकि IIS SQL सर्वर (या अन्य क्लासिक RDBMS) के एकल उदाहरण की तुलना में कहीं अधिक समवर्ती अनुरोधों को संभाल सकता है। हालाँकि, यदि आपका बैकएंड अधिक आधुनिक है - एक SQL सर्वर क्लस्टर, Azure SQL, NoSQL, आदि - और आपका बैकेंड स्केल कर सकता है, और आपकी स्केलेबिलिटी अड़चन IIS है, तो आप एक स्केलेबिलिटी लाभ प्राप्त कर सकते हैं async

तीसरा प्रश्न - मैं एक एकल क्रिया विधि में अतुल्यकालिक रूप से डेटाबेस क्वेरी करने के लिए कितनी बार प्रतीक्षा कर सकते हैं?

जितने चाहे उतने। हालांकि, ध्यान दें कि कई ओआरएम में एक-ऑपरेशन-प्रति-कनेक्शन नियम है। विशेष रूप से, EF केवल DbContext प्रति एकल ऑपरेशन की अनुमति देता है; यह सही है कि ऑपरेशन सिंक्रोनस है या एसिंक्रोनस।

इसके अलावा, अपने बैकएंड की मापनीयता को फिर से ध्यान में रखें। यदि आप SQL सर्वर का एक भी उदाहरण मार रहे हैं, और आपका IIS पहले से ही SQLServer को पूरी क्षमता पर रखने में सक्षम है, तो SQLServer पर दबाव को दोगुना या तिगुना करना आपकी मदद करने वाला नहीं है।


2
@seebiscuit: जब (उचित एसिंक्रोनस) I / O करते हैं, तो किसी थ्रेड का उपयोग नहीं किया जाता है। मेरे पास एक ब्लॉग पोस्ट है जो अधिक विस्तार से जाती है।
स्टीफन क्लीरी

2
IIS और एक एकल SQL सर्वर इंस्टेंस कितने अनुरोधों को संभाल सकता है? मैं ये नंबर कैसे पा सकता हूं?
MOD

1
@ एमओडी: यह कॉन्फ़िगरेशन और हार्डवेयर पर निर्भर करता है। इन नंबरों को खोजने का एकमात्र तरीका अपने स्वयं के सर्वर पर लोड परीक्षण करना है।
स्टीफन क्लीयर

1
@Flezcano: सीपीयू पर पूरी तरह से अमल करने वाले तरीके। यानी, वे I / O या ब्लॉकिंग नहीं करते हैं।
स्टीफन क्लीयर

1
क्षमा करें सर, लेकिन एसओ इस 2 लाइनर प्रश्न को स्वीकार नहीं करेंगे, जिसे मैं समझने की कोशिश कर रहा हूं। जब मैं इस चीज के लिए शोध कर रहा था जैसे कि अगर मेरे पास 1 वेब एपि अंत बिंदु है जिसे एक ही समय में 1000 उपयोगकर्ताओं द्वारा कॉल किया जाता है, तो क्या यह अंतिम बिंदु सक्षम होगा सर्वर इस हजार अनुरोध में से प्रत्येक या मैं अनुरोध के 1000 को संभालने के लिए यह async करना चाहिए?
लर्निंग-ओवरथिंकर-कन्फ्यूज़्ड

21

ASP.NET MVC में हर जगह async कार्रवाई का उपयोग करना अच्छा है?

प्रोग्रामिंग में हमेशा की तरह, यह निर्भर करता है । निश्चित मार्ग से नीचे जाने पर हमेशा व्यापार बंद रहता है।

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

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

उपयोग करते समय एक और बात ध्यान में रखना async-awaitतथ्य यह है कि यह सभी तरह से async है , जिसका अर्थ है कि आप async देखेंगे अपने पूरे कॉल स्टैक, नितोम के ऊपर। इसका मतलब है कि यदि आप सिंक्रोनस एपीआई को उजागर करना चाहते हैं, तो आप अक्सर खुद को एक निश्चित मात्रा में कोड डुप्लिकेट करते हुए पाएंगे, क्योंकि एसिंक्स और सिंक बहुत अच्छी तरह से मिश्रण नहीं करते हैं।

जब मैं डेटाबेस (EF / NHibernate / अन्य ORM के माध्यम से) को क्वेरी करना चाहता हूँ, तो मैं async / प्रतीक्षारत खोजशब्दों का उपयोग करता हूँ?

यदि आप async IO कॉल का उपयोग करने के रास्ते पर जाना चाहते हैं, तो हाँ, async-awaitएक अच्छा विकल्प होगा, क्योंकि अधिक से अधिक आधुनिक डेटाबेस प्रदाता TAP (टास्क एसिंक्रोनस पैटर्न) को लागू करने वाले async विधि को उजागर करते हैं।

कितनी बार मैं एक एकल क्रिया पद्धति में अतुल्यकालिक रूप से डेटाबेस क्वेरी करने के लिए प्रतीक्षित खोजशब्दों का उपयोग कर सकता हूं?

जब तक आप चाहें, जब तक आप अपने डेटाबेस प्रदाता द्वारा बताए गए नियमों का पालन करते हैं। आपके द्वारा किए जाने वाले एसिंक्स कॉल की मात्रा की कोई सीमा नहीं है। यदि आपके पास ऐसे प्रश्न हैं जो एक दूसरे से स्वतंत्र हैं और समवर्ती रूप से बनाए जा सकते हैं, तो आप प्रत्येक के लिए एक नया कार्य स्पिन कर सकते हैं और await Task.WhenAllदोनों को पूरा करने के लिए प्रतीक्षा करने के लिए उपयोग कर सकते हैं।


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

@PanagiotisKanavos मुझे पता है, कि मैं क्या कहा था से अस्पष्ट था?
युवल इट्ज़चकोव

1
आपके उत्तर में IIS बारीकियों का उल्लेख नहीं है - मेल्टडाउन / रीसायकल परिदृश्य पूरे async का उपयोग करने का एक प्राथमिक कारण है। जो किसी ने अनुभव नहीं किया है वह शायद यह नहीं समझ scale out wellसकता है कि इसका मतलब हो सकता है your server won't die under load। या यह एक मामला हो सकता हैonce burned ...
पानगीतिस कानावोस

7

मेरे 5 सेंट:

  1. का प्रयोग करें async/awaitयदि और केवल यदि आप एक आईओ आपरेशन, डीबी या बाह्य सेवा वेब सेवा की तरह करते हैं।
  2. हमेशा एसक्यूएल कॉल को डीबी पसंद करें।
  3. हर बार जब आप डीबी को क्वेरी करते हैं।

PS बिंदु 1 के लिए असाधारण मामले हैं, लेकिन आपको इसके लिए async इंटर्ल्स की अच्छी समझ होनी चाहिए।

अतिरिक्त लाभ के रूप में, यदि आवश्यक हो तो आप समानांतर में कुछ IO कॉल कर सकते हैं:

Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result

6

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


5

जैसा कि आप जानते हैं, MVC अतुल्यकालिक नियंत्रकों का समर्थन करता है और आपको इसका लाभ उठाना चाहिए। यदि आपका नियंत्रक लंबा ऑपरेशन करता है, (यह डिस्क आधारित I / o या किसी अन्य दूरस्थ सेवा के लिए नेटवर्क कॉल हो सकता है), यदि अनुरोध को सिंक्रोनस तरीके से हैंडल किया जाता है, तो IIS थ्रेड पूरे समय व्यस्त रहता है। नतीजतन, धागा बस लंबे ऑपरेशन के पूरा होने की प्रतीक्षा कर रहा है। अन्य अनुरोधों की सेवा करके इसका बेहतर उपयोग किया जा सकता है, जबकि पहले अनुरोध किया गया कार्य प्रगति पर है। इससे अधिक समवर्ती अनुरोधों को पूरा करने में मदद मिलेगी। आपका webservice अत्यधिक स्केलेबल होगा और आसानी से C10k समस्या में नहीं चलेगा । Db प्रश्नों के लिए async / wait का उपयोग करना एक अच्छा विचार है। और हाँ आप उन्हें कई बार उतने ही बार उपयोग कर सकते हैं जितना आप फिट हैं।

उत्कृष्ट सलाह के लिए यहां एक नज़र डालें ।


3

मेरा अनुभव है कि आज बहुत सारे डेवलपर्स async/awaitनियंत्रकों के लिए एक डिफ़ॉल्ट के रूप में उपयोग करते हैं ।

मेरा सुझाव होगा, इसका उपयोग तभी करें जब आपको पता हो कि यह आपकी मदद करेगा

इसका कारण है, जैसा कि स्टीफन क्लीरी और अन्य ने पहले ही उल्लेख किया है, यह उन्हें हल करने के बजाय प्रदर्शन के मुद्दों को पेश कर सकता है, और यह केवल एक विशिष्ट परिदृश्य में आपकी मदद करेगा:

  • हाई-ट्रैफिक कंट्रोलर
  • स्केलेबल बैकएंड

2

क्या ASP.NET MVC में हर जगह async कार्रवाई का उपयोग करना अच्छा है?

ऐसा करना अच्छा है जहाँ आप विशेष रूप से एक async पद्धति का उपयोग कर सकते हैं जब आपके पास कार्यकर्ता प्रक्रिया स्तर पर प्रदर्शन समस्याएँ होती हैं जो बड़े पैमाने पर डेटा और गणना कार्यों के लिए होती हैं। अन्यथा, कोई ज़रूरत नहीं है क्योंकि यूनिट परीक्षण के लिए कास्टिंग की आवश्यकता होगी।

प्रतीक्षा करने योग्य तरीकों के बारे में: क्या मैं किसी डेटाबेस (EF / NHibernate / अन्य ORM के माध्यम से) को क्वेरी करना चाहता हूँ, तो मैं async / प्रतीक्षा कीवर्ड का उपयोग कर सकता हूँ?

हां, किसी भी DB ऑपरेशन के लिए async का उपयोग करना बेहतर है, जितना संभव हो वर्कर प्रक्रियाओं के स्तर पर प्रदर्शन के मुद्दों से बचने के लिए। ध्यान दें कि EF ने अधिकांश कार्यों के लिए कई async विकल्प बनाए हैं, जैसे:

.ToListAsync()
.FirstOrDefaultAsync()
.SaveChangesAsync()
.FindAsync()

डेटाबेस में एक एकल क्रिया विधि में असमान रूप से क्वेरी करने के लिए मैं कितनी बार प्रतीक्षित खोजशब्दों का उपयोग कर सकता हूँ?

बस, अब बहुत हो चुका


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