2011-08-10 9 views
13

मैं अपने हाथों को एसिंक सीटीपी के साथ गंदे करने की कोशिश कर रहा हूं और मैंने देखा कि संकलक एसिंक रिटर्न प्रकार के बारे में शिकायत करता है। अन्य प्रकारों में समस्या क्या है?क्यों एसिंक का लौटा प्रकार शून्य, कार्य या कार्य <T>

एक साधारण डेमो

static void Main(string[] args) 
{ 
    DoWork(); 
    Console.WriteLine("Returned to main"); 
    Console.Read(); 
} 

// why do I need to return void, Task or Task<T> here? 
// I know I can use something like Task<IEnumerable<string>> 
private static async string[] DoWork() 
{ 
    Console.WriteLine("DoWork started"); 
    return await Task.Factory.StartNew(
     delegate 
     { 
      Thread.Sleep(2000);     
      Console.WriteLine("DoWork done"); 
      return new List<string>(); 
     });   
} 

उत्तर

11

await [खपत] पक्ष पर, हम लचीले हैं: हम किसी भी प्रकार का इंतजार कर सकते हैं जब तक कि सही तरीके हैं।

async विधि [उत्पादन] पक्ष पर, हम अनावश्यक हैं: हम पर हार्ड-कोड किए गए हैं केवल कार्य प्रकार (या शून्य) लौटाते हैं। असंगतता क्यों?

  1. Iterators पहले से ही इस व्यवहार है ...

    एक इटरेटर विधि (एक जो एक "उपज" अंदर है) हार्ड-कोडेड या तो IEnumerable या IEnumerator वापस जाने के लिए है। हालांकि, आप किसी भी प्रकार पर "foreach" कर सकते हैं जिसमें GetEnumerator/MoveNext/Current सदस्य हैं। तो Async बस सूट का पालन कर रहा है।

  2. एक काम के लिए एक भविष्य की तरह है, तो यह कड़ी मेहनत से कोड यह अच्छा है ...

    एक टास्क एक भविष्य की तुलना में मुश्किल से अधिक है। भविष्य एक भाषा/मंच का मूल मौलिक हिस्सा है। किसी भाषा के लिए कोई कारण नहीं है कि इस तरह के मौलिक धारणा की कई प्रतियां हैं। एक काफ़ी हैं। यह इतना आधारभूत है कि आप वायदा से निपटने के लिए भाषा में कीवर्ड भी जोड़ सकते हैं। वैसे भी, अगर किसी के पास भविष्य की तरह चीज है, या कार्य की समृद्ध धारणा है, तो वे इसे कार्य या Func से बाहर कर सकते हैं। (हमारे कार्य पहले से चल रहे हैं। अगर आप कुछ ऐसा करना चाहते हैं जो "ठंडा" है, जैसे कि F # एसिंक या IObservable की तरह, जो तब तक शुरू नहीं होता है जब तक आप इसे नहीं बताते - तो आपको इसे फ़नक से बाहर बनाना चाहिए एक कार्य से बाहर)।

  3. आगे बारीकियों

    इस समारोह को परिभाषित करें:

    void f<T>(Func<Task<T>> f) 
    

    और यह आह्वान:

    f(() => 1 + await t) 
    

    हम इस में अनुमान लगाने के लिए कि टी = पूर्णांक में सक्षम होना चाहते हैं मामला। इस तरह की अनुमान तब तक संभव नहीं है जब तक कंपाइलर को कड़ी-कोडित ज्ञान हो कि लैम्बडा इसे "एफ" में पास करता है, Task<int> टाइप करता है।

स्रोत: Technical intro to the Async CTP

6

क्योंकि एक Task<TResult> एक "भविष्य" है - एक मूल्य है कि बाद साथ आ रहे हैं। एक string[] आपके पास अभी कुछ है।

इसी प्रकार, Task एक ऐसा ऑपरेशन है जो भविष्य में कभी-कभी (या तो सफलतापूर्वक या त्रुटि के साथ) पूरा हो जाएगा।

void एक विशेष मामला है; यह Async सीटीपी में एक शीर्ष स्तरीय ऑपरेशन का प्रतिनिधित्व करता है।

यदि आप सोच रहे हैं कि Task स्वचालित रूप से अनुमानित क्यों नहीं है, तो इसे Async CTP टीम द्वारा अस्वीकार कर दिया गया था। उनका तर्क here है, और this thread भी इसे शामिल करता है।

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