2012-08-24 15 views
6

उम्मीद है कि यह दोहराना नहीं है, लेकिन यहां 5000+ प्रश्न हैं "सभी कोड पथ एक मूल्य वापस नहीं करते"!यह async/प्रतीक्षा कोड क्यों उत्पन्न करता है "... सभी कोड पथ एक मान वापस नहीं करते हैं"?

केवल, क्यों एक गैर सामान्य कार्यान्वयन के साथ इस पद्धति ठीक संकलित करता है:

public static async Task TimeoutAfter(this Task task, int millisecondsTimeout) 
    { 
     if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout))) 
      await task; 
     else 
      throw new TimeoutException(); 
    } 

जबकि विधि सामान्य बनाने के लिए यह प्रयास एक Return state missing/... not all code paths return a value चेतावनी/त्रुटि उत्पन्न ?:

public static async Task<T> TimeoutAfter<T>(this Task<T> task, int millisecondsTimeout) 
    { 
     if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout))) 
      await task; 
     else 
      throw new TimeoutException(); 
    } 
+0

@LB \ * "* * वापसी' Task' और ... –

उत्तर

8

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

MSDN reference से async कीवर्ड पर विशेष रूप से वापसी प्रकारों के बारे में उद्धरण।

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

+2

मेरी समझ जाता है कि इंतजार अभिव्यक्ति के मूल्य * आवेदन किया है * , इसलिए यह शून्य लौटने के बराबर नहीं है, हालांकि अपने आप में प्रतीक्षा है 'System.Void'। –

+1

यह सच है कि विधि पूरी तरह से' कार्य 'वापस लौटाती है जिसे आप प्रतीक्षा कर सकते हैं। यह शून्य है कि आप को अनुमति नहीं है विधि से एक मूल्य वापस करें और उस विधि का इंतजार करने के परिणामस्वरूप कुछ भी असाइन नहीं किया जा सकता है। 'कार्य ' के मामले में, आपके द्वारा लौटाया जाने वाला 'टी' फिर प्रतीक्षा से असाइन किया जा सकता है (उदाहरण के लिए 'var value = someCall प्रतीक्षा करें(); ') –

+0

धन्यवाद, महान स्पष्टीकरण। यह अब पूरी समझ में आता है, लेकिन शुरुआत में abstr की परत निर्माण की कार्रवाई मुझे फेंक रहा था। – HolySamosa

7

दूसरे उदाहरण में आपने दिया कि आपने कुछ भी वापस नहीं किया है। (क्यों क्रिस हनन का जवाब देखें)।

public static async Task<T> TimeoutAfter<T>(this Task<T> task, int millisecondsTimeout) { 
    if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout))) 
     return await task; // return the Task of T 
    else 
     throw new TimeoutException(); 
} 
क्या @ChrisHannon कहा, await documentation से के अलावा

... अगर await एक विधि कॉल है कि एक Task<TResult> देता है, तो इंतजार अभिव्यक्ति के प्रकार TResult है का परिणाम के लिए आवेदन किया है। यदि await एक विधि कॉल के परिणाम पर लागू होता है जो Task देता है, तो प्रतीक्षा अभिव्यक्ति का प्रकार void है। ...

+0

धन्यवाद, डेविड। मैं उदाहरण के रिटर्न मान पर की सराहना करनी चाहिए। – HolySamosa

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