कैसे एक खोजशब्द के बारे में नहीं है?
मैं संकलक को यह महसूस करना चाहता हूं कि, ज्यादातर समय, जब मैं एक अतुल्यकालिक विधि कहता हूं, तो मुझे इसका परिणाम चाहिए।
Document doc = DownloadDocumentAsync();
बस। लोगों को इस चीज़ के लिए एक कीवर्ड के बारे में सोचने में एक कठिन समय हो रहा है, क्योंकि यह एक कीवर्ड के लिए है "जैसे कि अगर आप पूरी तरह से सामान्य थे तो वह काम करेंगे जो आप करते हैं"। यह डिफ़ॉल्ट होना चाहिए, एक कीवर्ड की आवश्यकता नहीं है।
अपडेट करें
मैंने मूल रूप से सुझाव दिया कि संकलक को यह पता लगाने के लिए कि क्या करना है के प्रकार के साथ चतुर होना चाहिए। इसके बारे में और सोचने के बाद, मैं मौजूदा कार्यान्वयन को CTP में यथावत रखता हूँ, लेकिन इसमें कुछ जोड़-घटाव करते हैं, ताकि उन मामलों को कम किया जा सके जहाँ आपको await
कीवर्ड का स्पष्ट रूप से उपयोग करने की आवश्यकता होगी ।
हम एक विशेषता का आविष्कार करते हैं [AutoAwait]
:। यह केवल विधियों पर लागू किया जा सकता है। इसे अपनी विधि पर लागू करने का एक तरीका यह है कि आप इसे चिह्नित करें async
। लेकिन आप इसे हाथ से भी कर सकते हैं, जैसे:
[AutoAwait]
public Task<Document> DownloadDocumentAsync()
फिर किसी भी async
विधि के अंदर , कंपाइलर मान जाएगा कि आप कॉल का इंतजार करना चाहते हैं DownloadDocumentAsync
, इसलिए आपको इसे निर्दिष्ट करने की आवश्यकता नहीं है। उस पद्धति का कोई भी कॉल स्वचालित रूप से इसकी प्रतीक्षा करेगा।
Document doc = DownloadDocumentAsync();
अब, यदि आप "चतुर होना चाहते हैं" और प्राप्त करते हैं Task<Document>
, तो आप एक ऑपरेटर का उपयोग करते हैं start
, जो केवल एक विधि कॉल से पहले दिखाई दे सकता है:
Task<Document> task = start DownloadDocumentAsync();
नीट, मुझे लगता है। अब एक सादे विधि कॉल का अर्थ है कि इसका आम तौर पर क्या मतलब है: विधि के पूरा होने की प्रतीक्षा करें। और start
कुछ अलग इंगित करता है: रुको मत।
किसी async
विधि के बाहर दिखाई देने वाले कोड के लिए , आपको जिस [AutoAwait]
विधि से कॉल करने की अनुमति दी जाती है, वह केवल उसी के साथ उपसर्ग करके होती है start
। यह आपको ऐसा कोड लिखने के लिए मजबूर करता है जिसका एक ही अर्थ है चाहे वह किसी async
विधि में दिखाई दे या नहीं।
फिर मुझे लालच आने लगता है! :)
सबसे पहले, मैं async
इंटरफ़ेस विधियों पर लागू करना चाहता हूं :
interface IThing
{
async int GetCount();
}
इसका मूल रूप से यह अर्थ है कि कार्यान्वयन विधि को वापस लौटना चाहिए Task<int>
या कुछ संगत होना चाहिए await
, और विधि से कॉल करने वालों को [AutoAwait]
व्यवहार मिलेगा ।
इसके अलावा जब मैं उपरोक्त विधि को लागू करता हूं, मैं लिखना चाहता हूं:
async int GetCount()
इसलिए मुझे Task<int>
रिटर्न प्रकार के रूप में उल्लेख नहीं करना है ।
इसके अलावा, मैं async
प्रतिनिधि प्रकारों पर आवेदन करना चाहता हूं (जो, आखिरकार, एक विधि के साथ इंटरफेस की तरह हैं)। इसलिए:
public async delegate TResult AsyncFunc<TResult>();
एक async
प्रतिनिधि के पास है - आपने यह अनुमान लगाया - [AutoAwait]
व्यवहार। एक async
विधि से आप इसे कॉल कर सकते हैं और यह स्वचालित रूप से await
एड हो जाएगा (जब तक कि आप start
इसे नहीं चुनते )। और इसलिए यदि आप कहते हैं:
AsyncFunc<Document> getDoc = DownloadDocumentAsync;
वह सिर्फ काम करता है। यह एक विधि कॉल नहीं है। अभी तक कोई कार्य शुरू नहीं किया गया है - async delegate
एक कार्य नहीं है। यह कार्य करने के लिए एक कारखाना है। तुम कह सकते हो:
Document doc = getDoc();
और वह एक कार्य शुरू करेगा और इसे समाप्त करने के लिए प्रतीक्षा करेगा और आपको परिणाम देगा। या आप कह सकते हैं:
Task<Document> t = start getDoc();
तो इसमें एक जगह जहां "प्लंबिंग" लीक है वह यह है कि अगर आप किसी async
विधि को एक प्रतिनिधि बनाना चाहते हैं , तो आपको एक async delegate
प्रकार का उपयोग करने के लिए जानना होगा । तो इसके बजाय Func
आपको कहना चाहिए AsyncFunc
, और इसी तरह। हालांकि एक दिन उस प्रकार की चीज को बेहतर प्रकार के अनुमान से तय किया जा सकता है।
एक और सवाल यह है कि यदि आप कहते हैं कि एक साधारण (गैर-एएसक्यूएन) पद्धति पर शुरू होना चाहिए तो क्या होना चाहिए। जाहिर है एक संकलन त्रुटि सुरक्षित विकल्प होगा। लेकिन अन्य संभावनाएं हैं।