सी # में async / वेट उपयोग के दिशा-निर्देश नहीं हैं जो अच्छी वास्तुकला और अमूर्त स्तर की अवधारणाओं के विरोधाभासी हैं?


103

यह प्रश्न C # भाषा की चिंता करता है, लेकिन मुझे उम्मीद है कि यह जावा या टाइपस्क्रिप्ट जैसी अन्य भाषाओं को कवर करेगा।

Microsoft .NET में अतुल्यकालिक कॉल का उपयोग करने पर सर्वोत्तम प्रथाओं की सिफारिश करता है। इन सिफारिशों के बीच, चलो दो चुनें:

  • Async विधियों के हस्ताक्षर बदलें ताकि वे टास्क या टास्क लौटाएँ <> (टाइपस्क्रिप्ट में, यह एक वादा होगा>>)
  • xxxsync () के साथ समाप्त होने के लिए async विधियों के नाम बदलें

अब, एक async एक द्वारा एक निम्न स्तर, तुल्यकालिक घटक की जगह, यह आवेदन के पूर्ण ढेर को प्रभावित करता है। चूंकि एसिंक्स / वेट का सकारात्मक प्रभाव केवल तभी होता है जब "सभी तरह से उपयोग किया जाता है", इसका मतलब है कि आवेदन में हर परत के हस्ताक्षर और विधि के नाम को बदलना होगा।

एक अच्छी वास्तुकला में अक्सर प्रत्येक परतों के बीच सार को शामिल करना शामिल होता है, जैसे कि दूसरों द्वारा निम्न-स्तरीय घटकों को प्रतिस्थापित करना ऊपरी स्तर के घटकों द्वारा अनदेखी नहीं है। C # में, एब्स्ट्रैक्ट इंटरफेस का रूप लेते हैं। यदि हम एक नया, निम्न-स्तरीय, एसिंक्स घटक पेश करते हैं, तो कॉल स्टैक में प्रत्येक इंटरफ़ेस को एक नए इंटरफ़ेस द्वारा संशोधित या प्रतिस्थापित किया जाना चाहिए। जिस तरह से एक कार्यान्वित वर्ग में एक समस्या (async या सिंक) हल की जाती है वह कॉल करने वालों के लिए छिपी (सार) नहीं है। कॉल करने वालों को यह जानना होगा कि क्या यह सिंक या एसिंक्स है।

"अच्छा आर्किटेक्चर" सिद्धांतों के विपरीत सर्वोत्तम प्रथाओं का एसिंक्रोनस / प्रतीक्षा नहीं है?

क्या इसका मतलब है कि प्रत्येक इंटरफ़ेस (IEnumerable, IDataAccessLayer कहते हैं) को उनके async समकक्ष (IAsyncEnumerable, IAsyncDataAccessLayer) की आवश्यकता होती है, ताकि उन्हें async निर्भरता के लिए स्विच करने के बाद स्टैक में प्रतिस्थापित किया जा सके?

यदि हम समस्या को थोड़ा और बढ़ाते हैं, तो क्या यह आसान नहीं होगा कि हर विधि को async मान लिया जाए (टास्क को वापस करने के लिए <> या वादा <>), और विधियों के लिए async कॉल को सिंक्रनाइज़ करने के लिए जब वे वास्तव में नहीं हों async? क्या यह भविष्य की प्रोग्रामिंग भाषाओं से अपेक्षित है?


5
जबकि यह एक महान चर्चा प्रश्न लगता है, मुझे लगता है कि यह बहुत ही राय आधारित है जिसका उत्तर यहां दिया जाना चाहिए।
व्यंग्यात्मक

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

25
@DocBrown मुझे लगता है कि यहां गहरा सवाल यह है कि "क्या सिस्टम के हिस्से को सिंक्रोनस से एसिंक्रोनस में बदला जा सकता है बिना उन हिस्सों के जो इस पर निर्भर होते हैं? मुझे लगता है कि इसका उत्तर स्पष्ट है "नहीं"। उस स्थिति में, मैं यह नहीं देखता कि कैसे "अच्छी वास्तुकला और लेयरिंग की अवधारणाएं" यहां लागू होती हैं।
व्यंग्यात्मक

6
@ कामुक: एक गैर-राय जवाब के लिए एक अच्छा आधार की तरह लगता है ;-)
डॉक्टर ब्राउन

5
@Gherman: क्योंकि C #, बहुत सी भाषाओं की तरह, अकेले रिटर्न प्रकार के आधार पर ओवरलोडिंग नहीं कर सकता। आप async विधियों के साथ समाप्त हो जाएँगे, जिनके सिंक समकक्षों के समान हस्ताक्षर हैं (सभी नहीं ले सकते CancellationToken, और जो लोग डिफ़ॉल्ट की आपूर्ति करना चाहते हैं)। मौजूदा सिंक विधियों को हटाना (और सभी कोड को लगातार तोड़ना) एक स्पष्ट गैर-स्टार्टर है।
जीरोन मोस्टर्ट

जवाबों:


111

आपका रंग क्या है?

आपको बॉब निस्ट्रॉम के व्हाट कलर इज योर फंक्शन 1 में रुचि हो सकती है ।

इस लेख में, उन्होंने एक काल्पनिक भाषा का वर्णन किया है जहाँ:

  • प्रत्येक फ़ंक्शन का रंग होता है: नीला या लाल।
  • एक लाल फ़ंक्शन नीले या लाल फ़ंक्शन को कॉल कर सकता है, कोई समस्या नहीं।
  • एक नीला फ़ंक्शन केवल नीले फ़ंक्शन को कॉल कर सकता है।

काल्पनिक होते हुए, यह प्रोग्रामिंग भाषाओं में काफी नियमित रूप से होता है:

  • C ++ में, एक "कास्ट" विधि केवल अन्य "कॉन्स्ट" विधियों को कॉल कर सकती है this
  • हास्केल में, एक गैर-आईओ फ़ंक्शन केवल गैर-आईओ फ़ंक्शन को कॉल कर सकता है।
  • C # में, एक सिंक फ़ंक्शन केवल सिंक फ़ंक्शन 2 कह सकता है ।

जैसा कि आपने महसूस किया है, इन नियमों के कारण, कोड फ़ंक्शन के चारों ओर लाल फ़ंक्शन फैलते हैं । आप एक को सम्मिलित करते हैं, और थोड़ा करके यह पूरे कोड आधार को उपनिवेशित करता है।

1 Bob Nystrom, ब्लॉगिंग के अलावा, डार्ट टीम का भी हिस्सा है और इस छोटे से क्राफ्टिंग इंटरप्रिटर्स सीरी को लिखा है; किसी भी प्रोग्रामिंग लैंग्वेज / कंपाइलर एफिशिएनाडो के लिए अत्यधिक अनुशंसित है।

2 बिल्कुल सच नहीं है, क्योंकि आप एक async फ़ंक्शन को कॉल कर सकते हैं और इसे वापस आने तक रोक सकते हैं, लेकिन ...

भाषा की सीमा

यह अनिवार्य रूप से एक भाषा / रन-टाइम सीमा है।

एम के साथ भाषा: एन सूत्रण, उदाहरण के लिए, इस तरह के Erlang और गो में, की जरूरत नहीं है asyncकार्य: प्रत्येक कार्य संभवतः async है और इसकी "फाइबर" बस निलंबित कर दिया जाएगा, बदली, और जब यह फिर से तैयार है में वापस बदली।

C # एक 1: 1 थ्रेडिंग मॉडल के साथ चला गया, और इसलिए गलती से अवरुद्ध होने वाले थ्रेड्स से बचने के लिए भाषा में सतह की समतलता का निर्णय लिया।

भाषा सीमाओं की उपस्थिति में, कोडिंग दिशानिर्देशों को अनुकूलित करना होगा।


4
IO फ़ंक्शंस में प्रसार करने की प्रवृत्ति होती है, लेकिन परिश्रम के साथ, आप ज्यादातर अपने कोड के प्रवेश बिंदुओं के पास (स्टैक के पास) कार्यों के लिए उन्हें अलग कर सकते हैं। आप ऐसा कर सकते हैं उन कार्यों को IO फ़ंक्शन कहते हैं और फिर अन्य फ़ंक्शन उनसे आउटपुट संसाधित करते हैं और आगे के IO के लिए आवश्यक किसी भी परिणाम को वापस करते हैं। मुझे लगता है कि यह शैली मेरे कोड अड्डों को प्रबंधित करने और उनके साथ काम करने में बहुत आसान बनाती है। मुझे आश्चर्य है कि अगर वहाँ समानता के साथ एक कोरोलरी है।
jpmc26

16
"एम: एन" और "1: 1" थ्रेडिंग से आपका क्या मतलब है?
कप्तान मैन

14
@CaptainMan: 1: 1 थ्रेडिंग का अर्थ है किसी एक अनुप्रयोग थ्रेड को एक OS थ्रेड में मैप करना, यह C, C ++, Java या C # जैसी भाषाओं में होता है। इसके विपरीत, एम: एन थ्रेडिंग का अर्थ है एम अनुप्रयोगों को एम ओएस थ्रेड्स को मैप करना; गो के मामले में, अर्लंग के मामले में एक एप्लिकेशन थ्रेड को "गोरोइन" कहा जाता है, इसे "अभिनेता" कहा जाता है, और आपने उन्हें "ग्रीन थ्रेड" या "फाइबर" के रूप में भी सुना होगा। वे समानता की आवश्यकता के बिना संगति प्रदान करते हैं। दुर्भाग्य से इस विषय पर विकिपीडिया लेख विरल है।
मैथ्यू एम।

2
यह कुछ हद तक संबंधित है, लेकिन मुझे यह भी लगता है कि यह "फ़ंक्शन रंग" विचार उन कार्यों पर भी लागू होता है जो उपयोगकर्ता से इनपुट पर ब्लॉक करते हैं, उदाहरण के लिए, मोडल डायलॉग बॉक्स, संदेश बॉक्स, कंसोल I / O, आदि के कुछ रूप, जो कि उपकरण हैं शुरुआत से ही ढांचा रहा है।
jrh

2
@MatthieuM। C # में एक OS थ्रेड प्रति एक एप्लिकेशन थ्रेड नहीं है और कभी नहीं किया। जब आप मूल कोड के साथ बातचीत कर रहे हों, और विशेष रूप से MS SQL में चल रहे हों तो यह बहुत स्पष्ट है । और निश्चित रूप से, सहकारी दिनचर्या हमेशा संभव थी (और इसके साथ सरल भी हैं async); वास्तव में, यह उत्तरदायी यूआई के निर्माण के लिए एक बहुत ही सामान्य पैटर्न था। क्या यह एरलांग जितना ही सुंदर था? नहीं। लेकिन यह अभी भी C :)
Luaan

82

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


27
इसका उत्तर इस IMO जितना ही सरल है। एक तुल्यकालिक और अतुल्यकालिक प्रक्रिया के बीच का अंतर कार्यान्वयन कार्यान्वयन नहीं है - यह एक शब्दार्थ रूप से भिन्न अनुबंध है।
एंट पी

11
@AntP: मैं असहमत हूँ कि यह इतना आसान है; यह C # भाषा में सरफेस करता है, लेकिन उदाहरण के लिए Go लैंग्वेज में नहीं। तो यह अतुल्यकालिक प्रक्रियाओं की एक अंतर्निहित संपत्ति नहीं है, यह मामला है कि दी गई भाषा में अतुल्यकालिक प्रक्रियाओं को कैसे मॉडल किया जाता है।
मैथ्यू एम।

1
@MatthieuM। हां, लेकिन asyncयदि आप चाहते हैं तो आप तुल्यकालिक अनुबंध प्रदान करने के लिए C # में विधियों का उपयोग कर सकते हैं । एकमात्र अंतर यह है कि गो डिफ़ॉल्ट रूप से अतुल्यकालिक है जबकि C # डिफ़ॉल्ट रूप से सिंक्रोनस है। asyncआपको दूसरा प्रोग्रामिंग मॉडल देता है - async एब्सट्रैक्शन (यह वास्तव में रनटाइम, टास्क शेड्यूलर, सिंक्रोनाइज़ेशन संदर्भ, वेटर कार्यान्वयन ...) पर निर्भर करता है।
लुआं

6

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

एक अर्थ में यह एक ऐसी विधि है जो अपवादों को फेंकती है और दूसरा जो "सुरक्षित" है और त्रुटि के मामले में भी नहीं फेंकेगा। इन विधियों को प्रदान करने के लिए कोडर किस बिंदु पर अत्यधिक है जो अन्यथा एक से दूसरे में परिवर्तित किया जा सकता है?

इसमें विचार के दो विद्यालय हैं: एक है कई विधियाँ बनाना, प्रत्येक एक और संभवतया निजी पद्धति को कॉल करने की अनुमति देता है जो कि अतुल्यकालिक होने के नाते वैकल्पिक पैरामीटर या व्यवहार में मामूली परिवर्तन प्रदान करने की संभावना है। अन्य को आवश्यक तरीके और आवश्यक संशोधनों को करने के लिए कॉलर को छोड़ने के लिए इंटरफ़ेस विधियों को कम से कम करना आवश्यक है।

यदि आप पहले स्कूल के हैं, तो आपके कॉल को दोगुना करने से बचने के लिए सिंक्रोनस और अतुल्यकालिक कॉल की ओर एक वर्ग को समर्पित करने का एक निश्चित तर्क है। Microsoft ने सोचा के इस स्कूल का पक्ष लेते हैं, और सम्मेलन द्वारा, Microsoft द्वारा पसंद की गई शैली के अनुरूप बने रहने के लिए, आपको भी एक Async संस्करण रखना होगा, उसी तरह जिस तरह से इंटरफेस लगभग हमेशा "I" से शुरू होता है। मुझे इस बात पर जोर दें कि यह गलत नहीं है , प्रति से, क्योंकि किसी प्रोजेक्ट में एक सुसंगत शैली को रखने के बजाय इसे "सही तरीका" और मौलिक रूप से किसी प्रोजेक्ट में जोड़ने वाले विकास के लिए शैली बदलना बेहतर है।

उस ने कहा, मैं दूसरे स्कूल का पक्ष लेता हूं, जो कि इंटरफ़ेस के तरीकों को कम करना है। अगर मुझे लगता है कि एक विधि को अतुल्यकालिक तरीके से बुलाया जा सकता है, तो मेरे लिए विधि अतुल्यकालिक है। कॉल करने वाला तय कर सकता है कि आगे बढ़ने से पहले उस कार्य के लिए इंतजार किया जाए या नहीं। यदि यह इंटरफ़ेस किसी लायब्रेरी का इंटरफ़ेस है, तो इस तरीके से ऐसा करना अधिक उचित है, जिसमें आपके द्वारा पदावनत या समायोजित करने के लिए आवश्यक विधियों की संख्या कम से कम हो। यदि इंटरफ़ेस मेरी परियोजना में आंतरिक उपयोग के लिए है, तो मैं प्रदान किए गए मापदंडों और नहीं "अतिरिक्त" विधियों के लिए अपने पूरे प्रोजेक्ट में हर आवश्यक कॉल के लिए एक विधि जोड़ूंगा, और फिर भी, केवल तभी जब विधि का व्यवहार पहले से ही कवर नहीं है एक मौजूदा विधि द्वारा।

हालांकि, इस क्षेत्र की कई चीजों की तरह, यह काफी हद तक व्यक्तिपरक है। दोनों दृष्टिकोणों में उनके पक्ष और विपक्ष हैं। Microsoft ने चर नाम की शुरुआत में अक्षरों के संकेत के प्रकार को जोड़ने का सम्मेलन भी शुरू किया, और "m_" यह इंगित करने के लिए कि यह एक सदस्य है, जैसे चर नामों के लिए अग्रणी m_pUser। मेरी बात यह है कि Microsoft भी अचूक नहीं है, और गलतियाँ भी कर सकता है।

कहा कि, यदि आपकी परियोजना इस Async सम्मेलन का अनुसरण कर रही है, तो मैं आपको सलाह दूंगा कि आप इसका सम्मान करें और शैली जारी रखें। और केवल एक बार जब आप अपनी खुद की एक परियोजना दी जाती है, तो आप इसे सबसे अच्छे तरीके से लिख सकते हैं जिसे आप फिट देखते हैं।


6
"रनटाइम में, एक एसिंक्रोन कॉल को सिंक्रोनस में बदलने के लिए एक तुच्छ है" मुझे यकीन नहीं है कि यह वास्तव में ऐसा है। .NET में, .Wait()विधि का उपयोग करना और पसंद करना नकारात्मक परिणाम पैदा कर सकता है, और js में, जहां तक ​​मुझे पता है, यह बिल्कुल भी संभव नहीं है।
अधिकतम ६३०

2
@ max630 मैंने यह नहीं कहा कि विचार करने के लिए समवर्ती मुद्दे नहीं हैं, लेकिन अगर यह शुरू में एक समकालिक कार्य था, तो संभावना है कि यह बैलगाड़ियों का निर्माण नहीं कर रहा है। उस ने कहा, तुच्छ का अर्थ "तुल्यकालिक में बदलने के लिए यहां डबल क्लिक करना" नहीं है। Js में, आप एक वादा उदाहरण लौटाते हैं, और उस पर हल कॉल करते हैं।
नील

2
हाँ, यह पूरी तरह से गधा में एक दर्द async वापस सिंक में परिवर्तित करने के लिए
Ewan

4
@Neil जावास्क्रिप्ट में, भले ही आप कॉल करें Promise.resolve(x)और फिर उस पर कॉलबैक जोड़ें, उन कॉलबैक को तुरंत निष्पादित नहीं किया जाएगा।
निकोल

1
@ यदि कोई इंटरफ़ेस एक अतुल्यकालिक विधि को उजागर करता है, तो यह अपेक्षा करना कि टास्क पर प्रतीक्षा करना गतिरोध पैदा नहीं करेगा, एक अच्छी धारणा नहीं है। यह दस्तावेज़ में वास्तव में सिंक्रोनस को दिखाने के लिए इंटरफ़ेस के लिए बहुत बेहतर है, प्रलेखन में एक वादा की तुलना में जो बाद के संस्करण में बदल सकता है।
कार्ल वॉल्श

2

आइए कल्पना करें कि आपको अपने हस्ताक्षर को बदलने के बिना कार्यों को कॉल करने में सक्षम करने का एक तरीका है।

यह वास्तव में अच्छा होगा और कोई भी आपको उनके नाम बदलने की सिफारिश नहीं करेगा।

लेकिन, वास्तविक अतुल्यकालिक कार्य, न केवल वे हैं जो एक और async फ़ंक्शन का इंतजार करते हैं, बल्कि सबसे निचले स्तर की संरचना उनके लिए कुछ है जो उनके async प्रकृति के लिए विशिष्ट है। जैसे

public class HTTPClient
{
    public HTTPResponse GET()
    {
        //send data
        while(!timedOut)
        {
            //check for response
            if(response) { 
                this.GotResponse(response); 
            }
            this.YouCanWait();
        }
    }

    //tell calling code that they should watch for this event
    public EventHander GotResponse
    //indicate to calling code that they can go and do something else for a bit
    public EventHander YouCanWait;
}

यह सूचना के उन दो बिट कि बुला कोड आदेश में एक async तरह से कोड चलने वाले चीजों की तरह करने के लिए की जरूरत है है Taskऔर asyncसंपुटित।

अतुल्यकालिक कार्यों को करने का एक से अधिक तरीका है, async Taskकेवल एक पैटर्न है जो कंपाइलर में रिटर्न प्रकारों के माध्यम से बनाया गया है ताकि आपको घटनाओं को मैन्युअल रूप से लिंक न करना पड़े


0

मैं मुख्य बिंदु को कम सी # नेस फैशन और अधिक सामान्य में संबोधित करूंगा:

"अच्छा आर्किटेक्चर" सिद्धांतों के विपरीत सर्वोत्तम प्रथाओं का एसिंक्रोनस / प्रतीक्षा नहीं है?

मैं कहूंगा कि यह केवल आपके एपीआई के डिज़ाइन में आपके द्वारा किए गए चुनाव और उपयोगकर्ता को आपके द्वारा दी जाने वाली पसंद पर निर्भर करता है।

यदि आप चाहते हैं कि आपके API का एक फ़ंक्शन केवल async हो तो नामकरण सम्मेलन का पालन करने में बहुत कम रुचि है। बस हमेशा टास्क <> / वादा <> / फ्यूचर <> / ... रिटर्न टाइप के रूप में, यह स्व दस्तावेज है। यदि एक सिंक्रनाइज़ेशन उत्तर चाहता है, तो वह अभी भी प्रतीक्षा करने में सक्षम होगा, लेकिन यदि वह हमेशा ऐसा करता है, तो यह थोड़ा बॉयलरप्लेट बनाता है।

हालाँकि अगर आप केवल अपना एपीआई सिंक बनाते हैं, तो इसका मतलब है कि अगर कोई उपयोगकर्ता इसे एएसक्यूएनस करना चाहता है, तो उसे इसके एसिंक्स भाग को स्वयं प्रबंधित करना होगा।

यह काफी अतिरिक्त काम कर सकता है, हालांकि यह उपयोगकर्ता को इस बारे में अधिक नियंत्रण भी दे सकता है कि वह कितने समवर्ती कॉल की अनुमति देता है, टाइमआउट, रिट्रीज और इतने पर।

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

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

हो सकता है कि कोई और व्यक्ति अपने अनुभव को इसके साथ साझा कर सकता है क्योंकि मेरे पास ऐसे सिस्टम के साथ अनुभव की कमी है।


2
@ मिरल आप दोनों संभावनाओं में "एक सिंक विधि से एक async विधि कॉल" का उपयोग किया है।
एड्रियन गलत

@ AdrianWragg तो मैंने किया; मेरे दिमाग में दौड़ की स्थिति रही होगी। मैं इसे ठीक कर दूंगा।
मिरल

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

(और इससे मैं निश्चित रूप से एक अवरोधक सिंक विधि का अर्थ करता हूं । आप एक ऐसी चीज को कॉल कर सकते हैं जो एक शुद्ध रूप से सीपीयू-बाउंड गणना को एक एस्किंस विधि से सिंक्रोनाइज़ करता है - हालाँकि आपको इसे तब तक करने से बचने की कोशिश करनी चाहिए जब तक आप यह नहीं जानते कि आप एक कार्यकर्ता संदर्भ में हैं UI संदर्भ के बजाय - लेकिन लॉक पर या I / O के लिए या किसी अन्य ऑपरेशन के लिए बेकार प्रतीक्षा कॉल को रोकना एक बुरा विचार है।)
मिरल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.