मैं नीचे आपके विशिष्ट प्रश्नों का उत्तर दूंगा, लेकिन आप केवल हमारे व्यापक लेखों को पढ़ने के लिए अच्छी तरह से करेंगे कि हमने कैसे उपज और प्रतीक्षा की।
https://blogs.msdn.microsoft.com/ericlippert/tag/continuation-passing-style/
https://blogs.msdn.microsoft.com/ericlippert/tag/iterators/
https://blogs.msdn.microsoft.com/ericlippert/tag/async/
इनमें से कुछ लेख अब पुराने हैं; उत्पन्न कोड कई मायनों में अलग है। लेकिन यह निश्चित रूप से आपको यह विचार देगा कि यह कैसे काम करता है।
इसके अलावा, यदि आप यह नहीं समझते हैं कि लैम्ब्डा को क्लोजर कक्षाओं के रूप में कैसे उत्पन्न किया जाता है, तो पहले समझें । यदि आपके पास लैम्बडास नहीं है, तो आप एसिंक्स के सिर या पूंछ नहीं बनाएंगे।
जब कोई प्रतीक्षा हो जाती है, तो रनटाइम को कैसे पता चलता है कि आगे किस कोड का निष्पादन करना चाहिए?
await
के रूप में उत्पन्न होता है:
if (the task is not completed)
assign a delegate which executes the remainder of the method as the continuation of the task
return to the caller
else
execute the remainder of the method now
वह मूल रूप से यह है। अद्वैत सिर्फ एक फैंसी वापसी है।
यह कैसे पता चलता है कि यह फिर से शुरू हो सकता है जहां इसे छोड़ दिया गया था, और यह कैसे याद करता है कि कहां है?
खैर, आप बिना इंतजार किए कैसे करते हैं ? जब विधि फू कॉल विधि बार, किसी तरह हम याद करते हैं कि फू के बीच में वापस कैसे आना है, तो foo अक्षुण्ण की सक्रियता के सभी स्थानीय लोगों के साथ, कोई फर्क नहीं पड़ता कि बार क्या करता है।
आपको पता है कि कोडांतरक में यह कैसे किया जाता है। फू के लिए एक सक्रियण रिकॉर्ड स्टैक पर धकेल दिया जाता है; इसमें स्थानीय लोगों के मूल्य शामिल हैं। कॉल के बिंदु पर foo में रिटर्न पता स्टैक पर धकेल दिया जाता है। जब बार किया जाता है, तो स्टैक पॉइंटर और इंस्ट्रक्शन पॉइंटर को फिर से सेट किया जाता है, जहां उन्हें होने की आवश्यकता होती है और जहां से छोड़ा गया है, वहां से फू चलता रहता है।
प्रतीक्षारत की निरंतरता बिल्कुल वैसी ही है, सिवाय इसके कि रिकॉर्ड को इस कारण से रखा जाए कि सक्रियता का क्रम ढेर नहीं बनता है ।
प्रतिनिधि जो कार्य की निरंतरता के रूप में देता है, उसमें (1) एक नंबर होता है, जो एक लुकअप टेबल का इनपुट होता है, जो इंस्ट्रक्टर पॉइंटर देता है, जिसे आपको आगे निष्पादित करने की आवश्यकता होती है, और (2) लोकल और टेम्परेरी के सभी मान।
वहाँ कुछ अतिरिक्त गियर है; उदाहरण के लिए, .NET में यह एक कोशिश ब्लॉक के बीच में शाखा करने के लिए अवैध है, इसलिए आप तालिका में एक कोशिश ब्लॉक के अंदर कोड का पता चिपका नहीं सकते हैं। लेकिन ये बहीखाता विवरण हैं। वैचारिक रूप से, सक्रियण रिकॉर्ड केवल ढेर पर चला जाता है।
वर्तमान कॉल स्टैक का क्या होता है, क्या यह किसी तरह से सहेजा जाता है?
वर्तमान सक्रियण रिकॉर्ड में प्रासंगिक जानकारी को पहले स्थान पर कभी नहीं रखा जाता है; यह गेट-गो से ढेर को आवंटित किया जाता है। (खैर, औपचारिक मापदंडों को स्टैक पर या रजिस्टरों में सामान्य रूप से पारित किया जाता है और फिर विधि शुरू होने पर एक ढेर स्थान पर कॉपी किया जाता है।)
कॉल करने वालों के सक्रियण रिकॉर्ड संग्रहीत नहीं हैं; प्रतीक्षा शायद उनके पास लौटने वाली है, याद रखें, इसलिए उन्हें सामान्य रूप से निपटाया जाएगा।
ध्यान दें कि यह प्रतीक्षा की सरलीकृत निरंतरता गुजर शैली, और सच्ची कॉल-के-साथ-चालू-निरंतरता संरचनाओं के बीच एक जर्मन अंतर है जो आप योजना जैसी भाषाओं में देखते हैं। उन भाषाओं में कॉलर्स में निरंतरता सहित संपूर्ण निरंतरता कॉल-सीसी द्वारा कैप्चर की जाती है ।
क्या होगा यदि कॉल करने की विधि प्रतीक्षा करने से पहले अन्य विधि कॉल करती है - तो स्टैक ओवरराइट क्यों नहीं किया जाता है?
वे विधि कॉल रिटर्न, और इसलिए उनके सक्रियण रिकॉर्ड अब प्रतीक्षा के बिंदु पर स्टैक पर नहीं हैं।
और कैसे पृथ्वी पर रनटाइम अपवाद और स्टैक के मामले में इस सब के माध्यम से अपना काम करेगा?
एक अनकहा अपवाद की स्थिति में, अपवाद को पकड़ा जाता है, कार्य के अंदर संग्रहीत किया जाता है, और जब कार्य के परिणाम को प्राप्त किया जाता है, तो उसे पुन: फेंक दिया जाता है।
उस सभी बहीखाते को याद करें जिसका मैंने पहले उल्लेख किया था? अपवाद शब्दार्थ अधिकार प्राप्त करना एक बहुत बड़ा दर्द था, मुझे आपको बताना चाहिए।
जब पैदावार हो जाती है, तो रनटाइम उस बिंदु का ट्रैक कैसे रखता है जहां चीजों को उठाया जाना चाहिए? इटरेटर स्थिति कैसे संरक्षित है?
उसी तरह। स्थानीय लोगों की स्थिति को ढेर पर ले जाया जाता है, और एक संख्या जो उस निर्देश का प्रतिनिधित्व करती है जिस पर MoveNext
अगली बार इसे फिर से शुरू करना चाहिए जिसे स्थानीय लोगों के साथ संग्रहीत किया जाता है।
और फिर, यह सुनिश्चित करने के लिए कि पुनरावृत्तियों को सही तरीके से संभाला जाता है, इट्रेटर ब्लॉक में गियर का एक गुच्छा है।