आपने अपने प्रश्न में कई प्रश्न पूछे। मैं उन्हें थोड़ा अलग कर दूंगा जितना आपने किया था। लेकिन पहले मैं सीधे सवाल का जवाब दूं।
हम सभी एक ऐसा कैमरा चाहते हैं जो हल्का, उच्च गुणवत्ता वाला और सस्ता हो, लेकिन जैसा कहा जाता है, आप उन तीन में से अधिकतम दो पर ही पहुंच सकते हैं। आप यहां उसी स्थिति में हैं। आप ऐसा समाधान चाहते हैं जो सिंक्रोनस और एसिंक्रोनस रास्तों के बीच कुशल, सुरक्षित और शेयर कोड हो। आप केवल उनमें से दो पाने जा रहे हैं।
मुझे तोड़ दो कि क्यों है। हम इस प्रश्न से शुरू करेंगे:
मैंने देखा कि लोग कहते हैं कि आप GetAwaiter().GetResult()
एक async विधि पर उपयोग कर सकते हैं और इसे अपने सिंक विधि से लागू कर सकते हैं? क्या वह धागा सभी परिदृश्यों में सुरक्षित है?
इस सवाल का मुद्दा यह है कि "क्या मैं सिंक्रोनस और असिंक्रोनस रास्तों को साझा कर सकता हूं? सिंक्रोनस पथ बनाकर बस एसिंक्रोनस वर्जन पर एक सिंक्रोनस प्रतीक्षा करें?"
मुझे इस बिंदु पर सुपर स्पष्ट होने दें क्योंकि यह महत्वपूर्ण है:
आप किसी व्यक्ति से किसी भी तरह की छेड़छाड़ को रोक सकते हैं ।
यह बहुत बुरी सलाह है। जब तक आपके पास यह सबूत न हो कि कार्य सामान्य रूप से या असामान्य रूप से पूरा हो गया है, तब तक अतुल्यकालिक कार्य से एक परिणाम प्राप्त करना बहुत खतरनाक है ।
यह बहुत बुरी सलाह है, इस कारण पर विचार करें। आप लॉन घास काटना चाहते हैं, लेकिन आपका लॉन घास काटने की मशीन ब्लेड टूट गया है। आप इस वर्कफ़्लो का पालन करने का निर्णय लेते हैं:
- एक वेब साइट से एक नया ब्लेड ऑर्डर करें। यह एक उच्च-विलंबता, अतुल्यकालिक ऑपरेशन है।
- समकालिक रूप से प्रतीक्षा करें - अर्थात, तब तक सोएं जब तक आपके हाथ में ब्लेड न हो ।
- समय-समय पर मेलबॉक्स की जांच करें कि क्या ब्लेड आ गया है।
- बॉक्स से ब्लेड निकालें। अब आपके हाथ में है।
- मावर में ब्लेड स्थापित करें।
- लॉन की घास काटो।
क्या होता है? आप हमेशा के लिए सोते हैं क्योंकि मेल की जांच का कार्य अब मेल के आने के बाद होने वाली किसी चीज़ पर आधारित होता है ।
यह है बहुत आसान इस स्थिति में पाने के लिए जब आप तुल्यकालिक एक मनमाना कार्य पर प्रतीक्षा करें। उस कार्य को शायद उस थ्रेड के भविष्य में शेड्यूल किया गया कार्य हो सकता है जो अब प्रतीक्षा कर रहा है , और अब वह भविष्य कभी नहीं आएगा क्योंकि आप इसका इंतजार कर रहे हैं।
यदि आप एक अतुल्यकालिक प्रतीक्षा करते हैं तो सब कुछ ठीक है! आप समय-समय पर मेल की जांच करते हैं, और जब आप प्रतीक्षा कर रहे होते हैं, तो आप एक सैंडविच बनाते हैं या अपने कर या जो भी करते हैं; जब आप प्रतीक्षा कर रहे हों तो आप काम करते रहें।
कभी सिंक्रोनाइज़ न करें। यदि कार्य किया जाता है, तो यह अनावश्यक है । यदि कार्य नहीं किया गया है, लेकिन वर्तमान थ्रेड को चलाने के लिए शेड्यूल किया गया है, तो यह अक्षम है क्योंकि वर्तमान थ्रेड प्रतीक्षा के बजाय अन्य कार्य की सर्विसिंग कर सकता है। यदि कार्य पूरा नहीं हुआ है और वर्तमान थ्रेड पर शेड्यूल चलता है, तो यह सिंक्रोनाइज़ करने के लिए लटका रहता है। जब तक आप पहले से ही यह नहीं जान लेते हैं कि कार्य पूरा हो चुका है , तब तक फिर से सिंक्रोनाइज़ करने का कोई अच्छा कारण नहीं है ।
इस विषय पर आगे पढ़ने के लिए, देखें
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
स्टीफन वास्तविक दुनिया के परिदृश्य की तुलना में मुझे बेहतर बताते हैं।
अब चलो "अन्य दिशा" पर विचार करें। क्या हम एसिंक्रोनस संस्करण बनाकर कोड साझा कर सकते हैं?
यही कारण है संभवतः और वास्तव में शायद निम्नलिखित कारणों के लिए एक बुरा विचार,।
यह अक्षम है अगर सिंक्रोनस ऑपरेशन उच्च-विलंबता IO कार्य है। यह अनिवार्य रूप से एक कार्यकर्ता को काम पर रखता है और उस कर्मचारी को तब तक सोता है जब तक कि एक कार्य पूरा नहीं हो जाता। थ्रेड्स काफी महंगे हैं । वे डिफ़ॉल्ट रूप से पता स्थान के एक लाख बाइट्स का उपभोग करते हैं, वे समय लेते हैं, वे ऑपरेटिंग सिस्टम संसाधन लेते हैं; आप बेकार काम करने वाले एक धागे को जलाना नहीं चाहते हैं।
थ्रेड को सुरक्षित रखने के लिए सिंक्रोनस ऑपरेशन नहीं लिखा जा सकता है।
यह है एक और अधिक उचित तकनीक अगर उच्च विलंबता काम प्रोसेसर बाध्य है, लेकिन आप शायद बस एक कार्यकर्ता धागा करने के लिए इसे बंद हाथ करने के लिए नहीं चाहते हैं तो यह तो है। आप संभवत: कार्य समानांतर लाइब्रेरी का उपयोग करके इसे अधिक से अधिक CPUs के साथ समानांतर करने के लिए उपयोग कर सकते हैं, आप संभवतः रद्दीकरण तर्क चाहते हैं, और आप केवल तुल्यकालिक संस्करण वह सब नहीं कर सकते, क्योंकि तब यह पहले से ही अतुल्यकालिक संस्करण होगा ।
आगे की पढाई; फिर, स्टीफन इसे बहुत स्पष्ट रूप से बताते हैं:
टास्क का उपयोग क्यों नहीं करना चाहिए।
https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-using.html
टास्क के लिए अधिक "करो और न करो" परिदृश्यों।
https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html
इसके बाद क्या होता है? कोड साझा करने की दोनों तकनीकें या तो गतिरोध या बड़ी अक्षमता को जन्म देती हैं। हम जिस निष्कर्ष पर पहुँचते हैं वह यह है कि आपको चुनाव करना चाहिए। क्या आप ऐसा प्रोग्राम चाहते हैं जो कुशल हो और सही हो और कॉल करने वाले को प्रसन्न करता हो, या क्या आप सिंक्रोनस और एसिंक्रोनस रास्तों के बीच कोड की एक छोटी मात्रा को डुप्लिकेट करके दर्ज किए गए कुछ कीस्ट्रोक्स को बचाना चाहते हैं? तुम दोनों मत जाओ, मुझे डर है।