async + प्रतीक्षा == समन्वयन?


24

इस पोस्ट पर असंतुष्ट वेब अनुरोध करने की बात करता है।

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


5
बिल्कुल नहीं। आपका कोड इस अर्थ में समकालिक है कि परिणाम प्राप्त होने तक कुछ भी नहीं होता है। हालाँकि, आपने संभवतः उस धागे को छोड़ दिया था जिसे आप तब तक चला रहे थे जब तक कि एसिंक्स विधि वापस नहीं आ जाती, तब आपको निष्पादन जारी रखने के लिए एक और धागा सौंपा जाता है।
R0MANARMY

2
यह है, लेकिन async के साथ आप एक ही समय में एक और async कर सकते हैं और फिर 2 का इंतजार कर सकते हैं, सिंक के साथ यह संभव नहीं है
शाफ़्ट फ्रीक

यहाँ एक लेख ( tomasp.net/blog/async-compilation-internals.aspx ) C # में async के कुछ अंडर-हुड पर चर्चा कर रहा है - यह C # और F # में एसिंक्रोनस प्रोग्रामिंग को कवर करने वाली श्रृंखला का हिस्सा है।
पौल

@ratchetfreak: हाँ, यह कहे बिना जाता है कि आप कई कॉल कर रहे हैं।
मृकफ

@ R0MANARMY: यदि आपका ऐप अन्य काम कर रहा है, तो हाँ और async + प्रतीक्षा का सक्षम बनाता है। अकिम कहते हैं कि यह सबसे अच्छा है! लेकिन उस बटन के लिए कोड को बटन_क्लिक हैंडलर, या ऐसे किसी इवेंट हैंडलर में न होने की कल्पना करें। यदि कोई आंख बंद करके कोड (async + wait lines) को किसी भी विधि से कॉपी करता है, तो इससे गलत धारणा बन सकती है कि आपका कोड async है, लेकिन वास्तव में ऐसा नहीं हो सकता है।
मर्चिफ़

जवाबों:


32

नहीं, निरंतरता केasync + await != sync कारण

MSDN 'एसिंक्रोनस और Await (C # और विजुअल बेसिक) के साथ अतुल्यकालिक प्रोग्रामिंग "से

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

उदाहरण के लिए async निष्पादन UI थ्रेड को ब्लॉक नहीं करेगा, और Some TextBox.Textडाउनलोड समाप्त होने के बाद अपडेट किया जाएगा

private async void OnButtonClick()
{
   SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}

बहुत अच्छी तरह से कहा!
मृकफ

क्या आप और अधिक विस्तार से बता सकते हैं। क्या आप कह रहे हैं ... कि इसके बिना ... आप यूआई के साथ बातचीत नहीं कर पाएंगे ... क्योंकि यह मुख्य धागे पर होगा। तो क्या इसका मतलब यह है कि यह केवल वेब के लिए लागू एक एप्लिकेशन प्रकार प्रोग्राम में लागू होता है जहां इंटरैक्शन वेब सर्वर थ्रेड से अलग है। तो अखरोट के खोल में यह केवल महत्वपूर्ण हो जाता है अर्थात सिंक नहीं * जब आपका मुख्य धागा चलने वाला धागा हो। क्या यह अनपेक्षित व्यवहार नहीं बनाएगा, अर्थात एक ऐप (1 मुख्य सूत्र) में दो बटन क्लिक किए गए .. लेकिन आपको पहला पूरा किए बिना 1 क्लिक करने में सक्षम होना चाहिए?
सीबकिट

किस बारे में Console.WriteLine(await GetStringOverNetwork());? क्या होगा यदि आपको अतुल्यकालिक आह्वान के उत्पादन की आवश्यकता है? क्या प्रोग्राम पहली पहुंच पर ब्लॉक करेगा, भले ही धागा संभावित रूप से निष्पादन को जारी रख सके?
एंड्रयू

6

नहीं, यह समान नहीं है।

आपका asyncकोड ब्लॉक awaitजारी रखने के लिए कॉल के लौटने की प्रतीक्षा कर रहा है, हालांकि आपके बाकी एप्लिकेशन प्रतीक्षा नहीं कर रहे हैं और अभी भी सामान्य की तरह जारी रह सकते हैं।

इसके विपरीत, एक तुल्यकालिक कॉल आपके पूरे एप्लिकेशन या थ्रेड को तब तक प्रतीक्षा करेगा जब तक कि कोड किसी अन्य चीज़ के साथ जारी रखने के लिए निष्पादित नहीं हो जाता।


क्या सिंक कॉल को async + प्रतीक्षा के रूप में लागू नहीं किया जा सकता है?
शाफ़्ट फ्राक

@ratchetfreak मुझे लगता है कि प्रतीक्षारत / async स्थापित करने के लिए कुछ ओवरहेड है, इसलिए मुझे नहीं लगता कि आप इसके साथ अपने पूरे एप्लिकेशन को कोड करना चाहते हैं। मैं केवल कोड के संभावित लंबे समय तक चलने वाले ब्लॉक को निष्पादित करने के लिए इसका उपयोग करता हूं ताकि यह मेरे अनुप्रयोगों को लॉक न करे। :)
राहेल

5

कृपया मुझे async / प्रतीक्षा के संबंध में चीजों को स्पष्ट करने की अनुमति दें।

जब प्रतीक्षा का सामना करना पड़ता है तो अंतर्निहित राज्य मशीन नियंत्रण को तुरंत वापस करने की अनुमति देती है। फिर, जब प्रतीक्षित कॉल पूरी हो जाती है, तो अंतर्निहित राज्य मशीन आवेगित कॉल के बाद लाइन पर फिर से शुरू करने की अनुमति देती है।

इसलिए, Async ब्लॉक अवरुद्ध नहीं है और न ही यह प्रतीक्षा कॉल समाप्त होने की प्रतीक्षा कर रहा है; प्रतीक्षा आदेश का सामना होने पर नियंत्रण तुरंत वापस आ जाता है।

अंतर्निहित राज्य मशीन async / प्रतीक्षा के उपयोग के पीछे "जादू" का हिस्सा है जो कि अप्रयुक्त और छूटी नहीं है।


2

मैं मन में एक ही सवाल के साथ इस पर ठोकर खाई, फिर भी प्रतिक्रियाओं को पढ़ने के बाद सवाल लंजर लगता है, "हुड के नीचे जादू" के संदर्भ में भ्रमित।

उपर्युक्त अतुल्यकालिक प्रोग्रामिंग से :

  • asyncकीवर्ड एक async विधि है, जो आप का उपयोग करने की अनुमति देता में एक विधि बदल जाता है awaitउसके शरीर में कीवर्ड।
  • जब awaitकीवर्ड लागू किया जाता है, तो यह कॉलिंग विधि को निलंबित कर देता है और जब तक प्रतीक्षित कार्य पूरा नहीं हो जाता है, तब तक इसकी कॉलगर्ल को नियंत्रित करता है।
  • awaitकेवल एक asyncविधि के अंदर इस्तेमाल किया जा सकता है ।

क्या संदर्भ है कि मुठभेड़ों awaitको अवरुद्ध किया जाता है?

  • जी हां । यह अनिवार्य रूप से निष्पादन के संदर्भ में एक ज्ञात स्थिति बनाए रखने के लिए एक स्थानीय सिंक बाधा है; सिवाय इसके कि अन्य संदर्भों, यदि कोई हो, शामिल नहीं हैं।

क्या बाकी का आवेदन ब्लॉक में है await?

  • यह इस बात पर निर्भर करता है कि आपका आवेदन कैसे लिखा गया है। यदि यह एक awaitही संदर्भ में क्रमिक रूप से लॉन्च किए गए निर्भर एड कार्यों की एक श्रृंखला है (देखें: कुछ async / प्रतीक्षा व्यवहार को समझने की कोशिश कर रहा है )

    await asyncCall1();
    await asyncCall2();  // waits for asyncCall1() to complete

    इस तरह से प्रत्येक awaitअगले एक की स्पॉनिंग को ब्लॉक करेगा।

    दूसरी ओर, समानांतर में लॉन्च किए गए समान आश्रित कार्य समानांतर में निष्पादित होंगे और संदर्भ केवल सम्मान पर अवरुद्ध होंगे। await:

    Task<int> t1 = asyncCall1();
    Task<string> t2 = asyncCall2();  // runs in parallel with asyncCall1()
    int val = await t1;
    string str = await t2;  // waits for asyncCall1() to complete

    सामान्य तौर पर, awaitपैदावार बाहरी संदर्भ में निष्पादित होती है, जहां से वर्तमान संदर्भ कहा जाता है। हालाँकि, यदि बाहरी संदर्भ स्वयं वर्तमान की प्रतीक्षा कर रहा है, तो यह awaitउसी संदर्भ में क्रमबद्ध s की तरह है ।

इसलिए, asyncलाभों को पुनः प्राप्त करने के लिए, किसी को कई समानांतर संदर्भों (यूआई, डेटा-क्लाइंट आदि) को चलाने के लिए एप्लिकेशन को डिज़ाइन करने की आवश्यकता होती है, फिर awaitएक संदर्भ में अन्य संदर्भों के लिए निष्पादन होता है, इसलिए संपूर्ण एप्लिकेशन किसी व्यक्ति पर ब्लॉक नहीं होगा await

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.