क्या यह संकर किस्म है? (उदाहरण के लिए, क्या मेरा .NET प्रोग्राम तब तक एक स्टैक का उपयोग करता है जब तक कि यह एक एसिंक्स कॉल को हिट नहीं करता है, तब तक किसी अन्य संरचना पर स्विच हो जाता है, जब तक कि स्टैक वापस उस स्थिति में नहीं आता है जहां यह अगले आइटमों के बारे में सुनिश्चित हो सकता है, आदि? )
मूल रूप से हाँ।
मान लीजिए हमारे पास है
async void MyButton_OnClick() { await Foo(); Bar(); }
async Task Foo() { await Task.Delay(123); Blah(); }
यहाँ एक बहुत ही सरल विवरण दिया गया है कि कैसे निरंतरता को पुन: परिभाषित किया जाता है। वास्तविक कोड काफी अधिक जटिल है, लेकिन इससे विचार पार हो जाता है।
आप बटन पर क्लिक करें। एक संदेश कतारबद्ध है। संदेश लूप संदेश को संसाधित करता है और स्टैक पर संदेश कतार का रिटर्न एड्रेस डालते हुए क्लिक हैंडलर को कॉल करता है। यानी हैंडलर करने के बाद जो चीज होती है वह यह है कि मैसेज लूप को चालू रखना है। तो हैंडलर की निरंतरता लूप है।
स्टैक पर खुद का रिटर्न एड्रेस डालते हुए क्लिक हैंडलर फू () कहता है। यही है, फू की निरंतरता क्लिक हैंडलर के शेष है।
फू टास्क को बुलाता है। डेल, स्टैक पर खुद का रिटर्न एड्रेस डालते हुए।
Task.Delay जो भी जादू करता है उसे तुरंत एक टास्क को वापस करने की आवश्यकता होती है। स्टैक आबाद है और हम फू में वापस आ गए हैं।
फू अपने काम को पूरा करने के लिए लौटा हुआ कार्य देखता है। यह नहीं। प्रतीक्षारत की निरंतरता ब्लाह () को कॉल करने के लिए है, इसलिए फू एक प्रतिनिधि बनाता है जो ब्लाह को बुलाता है (), और संकेत देता है कि कार्य की निरंतरता के रूप में। (मैंने अभी थोड़ा गलत बयान दिया है; क्या आपने इसे पकड़ा है? यदि नहीं, तो हम इसे एक पल में प्रकट कर देंगे।)
फू तब अपनी टास्क ऑब्जेक्ट बनाता है, इसे अपूर्ण के रूप में चिह्नित करता है, और इसे स्टैक को क्लिक हैंडलर को वापस करता है।
क्लिक हैंडलर फू के कार्य की जांच करता है और उसे पता चलता है कि यह अपूर्ण है। हैंडलर में प्रतीक्षा की निरंतरता बार () को कॉल करना है, इसलिए क्लिक हैंडलर एक प्रतिनिधि बनाता है जो बार () को कॉल करता है और इसे फू () द्वारा लौटाए गए कार्य की निरंतरता के रूप में सेट करता है। इसके बाद मैसेज लूप को स्टैक वापस करता है।
संदेश लूप संदेशों को संसाधित करता रहता है। आखिरकार देरी कार्य द्वारा बनाया गया टाइमर जादू अपनी बात करता है और कतार को एक संदेश पोस्ट करता है जो कहता है कि विलंब कार्य की निरंतरता अब निष्पादित की जा सकती है। इसलिए मैसेज लूप कार्य को निरंतरता कहता है, हमेशा की तरह स्टैक पर। उस प्रतिनिधि को ब्लाह कहते हैं ()। ब्लाह () जो करता है वही करता है और स्टैक को वापस करता है।
अब क्या होता है? यहाँ मुश्किल सा है। विलंब कार्य की निरंतरता केवल ब्लाह () को नहीं बुलाती है। इसे बार () को कॉल ट्रिगर करना पड़ता है, लेकिन यह कार्य बार के बारे में नहीं जानता है!
फू ने वास्तव में एक प्रतिनिधि बनाया जो (1) ब्ला को बुलाता है (), और (2) उस कार्य की निरंतरता को कहता है जिसे फू ने बनाया और वापस इवेंट हैंडलर को सौंप दिया। इसी तरह हम एक प्रतिनिधि को कॉल करते हैं जो बार () को कॉल करता है।
और अब हमने वह सब कुछ किया है जो हमें सही क्रम में करने की आवश्यकता थी। लेकिन हमने बहुत लंबे समय तक संदेश लूप में संदेशों को संसाधित करना बंद नहीं किया, इसलिए एप्लिकेशन उत्तरदायी रहा।
इन परिदृश्यों के लिए बहुत उन्नत हैं एक स्टैक सही समझ में आता है, लेकिन स्टैक की जगह क्या है?
प्रतिनिधियों के बंद वर्गों के माध्यम से एक दूसरे के संदर्भ में कार्य वस्तुओं का ग्राफ। वे क्लोजर क्लासेस राज्य मशीनें हैं जो सबसे हाल ही में निष्पादित प्रतीक्षा की स्थिति और स्थानीय लोगों के मूल्यों पर नज़र रखती हैं। साथ ही, दिए गए उदाहरण में, ऑपरेटिंग सिस्टम और संदेश लूप द्वारा कार्यान्वित क्रियाओं की एक वैश्विक-राज्य कतार जो उन कार्यों को निष्पादित करती है।
व्यायाम: आप यह कैसे मान लेते हैं कि यह दुनिया में बिना संदेश के काम करता है? उदाहरण के लिए, अनुप्रयोग कंसोल। कंसोल ऐप में इंतजार करना काफी अलग है; क्या आप यह जान सकते हैं कि जो आप अभी तक जानते हैं उससे यह कैसे काम करता है?
जब मैंने इस साल पहले के बारे में सीखा था, तो स्टैक वहां था क्योंकि यह तेज और हल्का था, ढेर से दूर आवेदन पर आवंटित स्मृति का एक टुकड़ा क्योंकि यह हाथ में कार्य के लिए अत्यधिक कुशल प्रबंधन का समर्थन करता था (उद्देश्य?)। क्या बदला है?
स्टैक एक उपयोगी डेटा संरचना है जब विधि सक्रियण के जीवनकाल एक स्टैक बनाते हैं, लेकिन मेरे उदाहरण में क्लिक हैंडलर, फू, बार और ब्लाह की सक्रियता एक स्टैक नहीं बनाते हैं। और इसलिए डेटा संरचना जो दर्शाती है कि वर्कफ़्लो एक स्टैक नहीं हो सकता है; बल्कि यह ढेर-आवंटित कार्यों और प्रतिनिधियों का एक ग्राफ है जो वर्कफ़्लो का प्रतिनिधित्व करता है। वर्कफ़्लो में वेव्स पॉइंट होते हैं जहाँ वर्कफ़्लो में प्रगति तब तक नहीं की जा सकती है जब तक कि काम पहले शुरू न हो जाए; जब हम प्रतीक्षा कर रहे हैं, हम अन्य कार्य निष्पादित कर सकते हैं जो उन विशेष रूप से शुरू किए गए कार्यों पर निर्भर नहीं होते हैं जो पूरे हो चुके हैं।
स्टैक केवल तख्ते की एक सरणी है, जहां फ़्रेम में कार्य (जहां कॉल हुआ था) और (2) स्थानीय चर और टेम्पों के मानों के बीच में (1) पॉइंटर्स होते हैं। कार्यों की निरंतरता एक ही बात है: प्रतिनिधि कार्य करने के लिए एक संकेतक है और इसमें एक राज्य है जो फ़ंक्शन के बीच में एक विशिष्ट बिंदु का संदर्भ देता है (जहां प्रतीक्षा हुई), और समापन में प्रत्येक स्थानीय चर या अस्थायी के लिए फ़ील्ड हैं । तख्ते अभी एक अच्छा स्वच्छ सरणी नहीं बनाते हैं, लेकिन सभी जानकारी समान है।