2012-01-07 18 views
74

क्या कोई इस बात की पुष्टि करने के लिए पर्याप्त दयालु हो सकता है कि क्या मैं Async कीवर्ड को सही तरीके से प्रतीक्षा कर रहा हूं? (सीटीपी के संस्करण 3 का उपयोग करके)क्या Async lambda के साथ जारी रखने के समान कीवर्ड का इंतजार कर रहा है?

अब तक मैंने काम किया है कि एक विधि कॉल से पहले प्रतीक्षा कीवर्ड डालने से अनिवार्य रूप से 2 चीजें होती हैं, ए। यह तत्काल वापसी करता है और बी। यह एक "निरंतरता" बनाता है Async विधि आमंत्रण के पूरा होने पर आह्वान किया जाता है। किसी भी मामले में निरंतरता विधि के लिए कोड ब्लॉक का शेष है।

तो मैं क्या सोच रहा हूं, कोड के इन दो बिट्स तकनीकी रूप से समकक्ष हैं, और यदि ऐसा है, तो इसका मूल अर्थ यह है कि प्रतीक्षा कीवर्ड लैम्ब्डा के साथ जारी रखने के समान है (आईई: इसका मूल रूप से एक के लिए एक कंपाइलर शॉर्टकट) ? यदि नहीं, मतभेद क्या हैं?

bool Success = 
    await new POP3Connector(
     "mail.server.com", txtUsername.Text, txtPassword.Text).Connect(); 
// At this point the method will return and following code will 
// only be invoked when the operation is complete(?) 
MessageBox.Show(Success ? "Logged In" : "Wrong password"); 

वी.एस.

(new POP3Connector(
    "mail.server.com", txtUsername.Text, txtPassword.Text).Connect()) 
.ContinueWith((success) => 
    MessageBox.Show(success.Result ? "Logged In" : "Wrong password")); 

उत्तर

73

सामान्य विचार सही है - विधि के शेष के प्रकार के एक निरंतरता में किया जाता है।

"fast path" blog post में async/await संकलक परिवर्तन कार्यों के बारे में विवरण है।

मतभेद, मेरे सिर के ऊपर से:

await कीवर्ड भी एक "शेड्यूलिंग संदर्भ" की अवधारणा का उपयोग करता है। शेड्यूलिंग संदर्भ SynchronizationContext.Current है यदि यह मौजूद है, तो TaskScheduler.Current पर वापस आना। निरंतरता शेड्यूलिंग संदर्भ पर चलती है। तो TaskScheduler.FromCurrentSynchronizationContextContinueWith में TaskScheduler.Current पर वापस गिरने के साथ निकटतम अनुमान होगा।

वास्तविक async/await कार्यान्वयन पैटर्न मिलान पर आधारित है; यह एक "प्रतीक्षा करने योग्य" पैटर्न का उपयोग करता है जो कार्यों के अलावा अन्य चीजों की प्रतीक्षा करता है। कुछ उदाहरण हैं WinRT एसिंक्रोनस एपीआई, Yield, आरएक्स वेरिएबल्स, और special socket awaitables that don't hit the GC as hard जैसे कुछ विशेष तरीकों। कार्य शक्तिशाली हैं, लेकिन वे एकमात्र प्रतीक्षा नहीं कर रहे हैं।

एक और मामूली नाइटपीकी अंतर दिमाग में आता है: यदि प्रतीक्षा करने योग्य पहले ही पूरा हो चुका है, तो async विधि वास्तव में उस बिंदु पर वापस नहीं आती है; यह तुल्यकालिक रूप से जारी है। तो यह TaskContinuationOptions.ExecuteSynchronously पास करने की तरह है, लेकिन ढेर से संबंधित समस्याओं के बिना।

+2

बहुत अच्छी तरह से कहा - मैं जॉन की पोस्ट को स्थगित करने की कोशिश करता हूं क्योंकि वे एसओ पर जवाब देने के लिए मेरे पास कुछ भी समय से ज्यादा व्यापक हैं, लेकिन स्टीफन का बिल्कुल सही अधिकार है। डब्लूआरटी क्या इंतजार कर रहा है (और विशेष रूप से GetAwaiter), उसकी पोस्ट # 3 बहुत उपयोगी आईएमएचओ है :) http://msmvps.com/blogs/jon_skeet/archive/2011/05/13/eduasync-part-3-the-shape- ऑफ-द-एसिंक-विधि-प्रतीक्षा योग्य-सीमा.aspx –

+4

यहां स्टीफन का स्थान। सरल उदाहरणों के लिए यह सोचना आसान है कि async/await केवल जारी रखने के लिए एक शॉर्टकट है - हालांकि, मुझे इसके विपरीत में इसके बारे में सोचना पसंद है। Async/प्रतीक्षा वास्तव में जारी रखने के लिए उपयोग की जाने वाली चीज़ों की एक अधिक शक्तिशाली अभिव्यक्ति है। मुद्दा यह है कि जारी (...) lambdas का उपयोग करता है, और निष्पादन को निरंतरता में स्थानांतरित करने की अनुमति देता है, लेकिन अन्य नियंत्रण प्रवाह अवधारणाएं जैसे लूप बहुत असंभव हैं यदि आपको जारी रखें (पहले ..) से पहले लूप बॉडी को आधा रखना है। ।) और दूसरे आधे के बाद। आप मैन्युअल निरंतरता श्रृंखला के साथ समाप्त होता है। –

+7

एक और उदाहरण जहां async/await जारी है()) अपवादों से बह रहा है की तुलना में अधिक अभिव्यक्तिपूर्ण है। आप एक ही प्रयास ब्लॉक के भीतर कई बार प्रतीक्षा कर सकते हैं, और निष्पादन के प्रत्येक चरण के लिए, उनके अपवादों को उसी पकड़ (...) ब्लॉक में फंसाया जा सकता है, जो स्पष्ट रूप से ऐसा कोड लिखने के बिना ब्लॉक करता है। –

8

यह "अनिवार्य" है कि, है, लेकिन उत्पन्न कोड सिर्फ इतना है कि तुलना में सख्ती से अधिक करता है। उत्पन्न कोड पर बहुत अधिक विस्तार के लिए, मैं अत्यधिक जॉन स्कीट के Eduasync श्रृंखला की सलाह देते हैं:

http://codeblog.jonskeet.uk/category/eduasync/

विशेष रूप से, के बाद # 7, क्या उत्पन्न हो जाता है में हो जाता है और यही कारण है (CTP 2) के रूप में तो शायद क्या आप इस समय के लिए देख रहे के लिए बेहद उपयुक्त:

http://codeblog.jonskeet.uk/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method/

संपादित करें: मुझे लगता है कि अधिक से अधिक विस्तार होने की संभावना क्या आप सवाल से की तलाश कर रहे हैं, लेकिन आप सोच रहे हैं कि जब आप विधि में एकाधिक प्रतीक्षा करते हैं तो क्या चीजें दिखती हैं, जो पोस्ट # 9 में शामिल है :)

http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/

संबंधित मुद्दे