C#5 Async/Await-क्या यह*समवर्ती*है?
continuations async-await (3)
मैं C # 5 में नए async सामान पर विचार कर रहा हूँ, और एक विशेष प्रश्न सामने आया
मैं समझता हूं कि await
कीवर्ड निरंतरता को लागू करने के लिए एक स्वच्छ संकलक चाल / वाक्यगत चीनी है, जहां शेष विधि को Task
ऑब्जेक्ट में तोड़ दिया जाता है और क्रम में चलाने के लिए कतारबद्ध किया जाता है, लेकिन जहां नियंत्रण कॉलिंग विधि में वापस आ जाता है ।
मेरी समस्या यह है कि मैंने सुना है कि वर्तमान में यह सब एक ही धागे पर है। क्या इसका मतलब यह है कि यह async सामान वास्तव में Task
ऑब्जेक्ट्स में निरंतरता कोड को बदलने और फिर अगले कार्य शुरू करने से पहले प्रत्येक कार्य के पूरा होने के बाद Application.DoEvents()
को कॉल करने का एक तरीका है?
या क्या मैं कुछ न कुछ भूल रहा हूं? (इस सवाल का हिस्सा बयानबाजी है - मैं पूरी तरह से जानता हूं कि मुझे कुछ याद आ रहा है :))
Async / इंतजार के पीछे पूरा विचार यह है कि यह निरंतर रूप से गुजरता हुआ प्रदर्शन करता है, और ऑपरेशन के लिए एक नया धागा आवंटित नहीं करता है। निरंतरता एक नए धागे पर हो सकती है, यह उसी धागे पर जारी रह सकती है ।
जिस तरह से मैं इसे समझाना चाहता हूं वह यह है कि "प्रतीक्षा" कीवर्ड बस एक कार्य के समाप्त होने की प्रतीक्षा करता है लेकिन प्रतीक्षा करते समय कॉलिंग थ्रेड को निष्पादन देता है। यह तब टास्क का परिणाम देता है और टास्क पूरा होने के बाद "प्रतीक्षा" कीवर्ड के बाद के स्टेटमेंट से जारी रहता है।
जिन लोगों पर मैंने गौर किया है, उन्हें लगता है कि टास्क को कॉलिंग थ्रेड के रूप में एक ही थ्रेड में चलाया जाता है, यह गलत है और कॉल का इंतजार करने वाली विधि के भीतर एक Windows.Forms GUI तत्व को बदलने की कोशिश करके इसे साबित किया जा सकता है। हालांकि, कॉलिंग थ्रेड में निरंतरता चलती है जहां कभी भी संभव है।
टास्क पूरा होने पर कॉलबैक डेलीगेट्स या इवेंट हैंडलर न होने का इसका सिर्फ एक साफ तरीका है।
वास्तविक "मांस" (एसिंक्रोनस) का हिस्सा एस्किंस / वेट का हिस्सा आम तौर पर अलग से किया जाता है और कॉल करने वाले के लिए संचार टास्क कॉमप्लेक्शन सोर्स के माध्यम से किया जाता है। जैसा कि यहाँ लिखा है http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx
TaskCompletionSource प्रकार दो संबंधित उद्देश्यों को पूरा करता है, दोनों को इसके नाम से दिया गया है: यह एक कार्य बनाने के लिए एक स्रोत है, और उस कार्य के पूरा होने के लिए स्रोत है। संक्षेप में, एक TaskCompletionSource एक कार्य और उसके पूरा होने के लिए निर्माता के रूप में कार्य करता है।
और उदाहरण काफी स्पष्ट है:
public static Task<T> RunAsync<T>(Func<T> function)
{
if (function == null) throw new ArgumentNullException(“function”);
var tcs = new TaskCompletionSource<T>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
T result = function();
tcs.SetResult(result);
}
catch(Exception exc) { tcs.SetException(exc); }
});
return tcs.Task;
}
TaskCompletionSource
माध्यम से आपके पास एक Task
ऑब्जेक्ट तक पहुंच होती है जिसका आप इंतजार कर सकते हैं, लेकिन यह TaskCompletionSource
/ प्रतीक्षा कीवर्ड के माध्यम से नहीं है जिसे आपने मल्टीथ्रेडिंग बनाया है।
ध्यान दें कि जब कई "धीमे" कार्य async / प्रतीक्षा सिंटैक्स में परिवर्तित हो जाएंगे, तो आपको TaskCompletionSource
का उपयोग करने की आवश्यकता नहीं होगी। वे आंतरिक रूप से इसका उपयोग करेंगे (लेकिन अंत में कहीं एक TaskCompletionSource
होना चाहिए जिसमें एक अतुल्यकालिक परिणाम हो)