2011-07-21 16 views
17

async के साथ नवीनतम CTP5 का उपयोग करते हुए/इंतजार कीवर्ड, मैं कुछ कोड है, जो जाहिरा तौर पर संकलन नहीं कर सकते हैं लिखा है:सरल async विधि कैसे लिखें?

class Program 
    { 
     public class MyClass 
     { 
      async public Task<int> Test() 
      { 
       var result = await TaskEx.Run(() => 
        { 
         Thread.Sleep(3000); 
         return 3; 
        }); 
       return result; 
      } 
     } 

     static void Main(string[] args) 
     { 
      var myClass = new MyClass(); 

      //The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error ??!! 
      int result = await myClass.Test(); 

      Console.ReadLine(); 
     } 
    } 

क्या 'की' का इंतजार है 'ऑपरेटर केवल एक विधि में इस्तेमाल किया जा सकता है या लैम्ब्डा के साथ चिह्नित वें कारण है 'async' संशोधक त्रुटि? "

उत्तर

8

अगर आप async के रूप में मुख्य चिह्नित कर सकते हैं मैं नहीं जानता कि (मैं रेखा है जो दृश्य स्टूडियो मुझे को इंगित का चयन किया है), लेकिन आप किसी भी विधि await का उपयोग करता है की घोषणा में async कीवर्ड शामिल करने के लिए की जरूरत है। उदाहरण के लिए:

public async void DoStuffAsync() 
{ 
    var myClass = new MyClass(); 

    int result = await myClass.TestAsync(); 
} 
+1

आप * * 'async' के रूप में घोषणा कर सकते हैं' Main', और 'उस में कुछ भी * * अपने कार्यक्रम खत्म हो जाएगा await'ing – dlev

+0

(यह मानते हुए आपके द्वारा चलाए जा कोई अन्य अग्रभूमि धागे की है।) दुह, मैंने सोचा कि त्रुटि मेरी टेस्ट विधि के अंदर है। विजुअल स्टूडियो को इस त्रुटि के साथ अधिक जानकारीपूर्ण होना चाहिए (जैसे "विधि मुख्य एसिंक होना चाहिए") – ghord

+8

सी # 5 रिलीज में, यदि आप मुख्य को एसिंक के रूप में चिह्नित करते हैं, तो आपको एक त्रुटि मिलती है: "एक प्रविष्टि बिंदु को 'async' के साथ चिह्नित नहीं किया जा सकता 'संशोधक " – Anthony

4

awaitWait() के रूप में ही नहीं है, await कर रहा है उस विधि का एक महत्वपूर्ण पुन: लेखन है, और विशेष रूप से कॉलर को यह तरीका कैसे निकलता है इसकी अपेक्षा को प्रभावित करता है। आप सही हैं कि वास्तव में अधिक (चेतावनी: वापसी प्रकार) को कुछ चीजों को सक्षम करने के लिए संकलक को बताएं (जैसे unsafe, checked और unchecked जैसे स्विच करें) - लेकिन विचार करें: यह वास्तव में आपके उदाहरण में बड़े पैमाने पर मायने रखता है। यदि Main() निकलता है (और हम कोई अन्य धागे नहीं मानते हैं) - आप exast टोस्ट है। गया हुआ। अब मौजूद नहीं है। async जोड़ा जा रहा है आप समझते हैं कि सिर्फ इसलिए कि विधि बाहर निकालता है मतलब यह नहीं है यह समाप्त हो गया है बनाता है। आप तैयार होने से पहले Main() बाहर निकलना नहीं चाहते हैं।

एक माध्यमिक प्रभाव के रूप में, इस स्विच भी formalises कि विधि केवल Task तरह बातें लौट सकते हैं; स्विच के बिना, आप इसे बाद में एसिंक बनाने के लिए प्रेरित हो सकते हैं, जो एक महत्वपूर्ण तोड़ने वाला परिवर्तन हो सकता है।

+2

यह एक * पूर्व * कार्यक्रम है। – dlev

+0

@dlev अच्छा मॉन्टी पायथन वहाँ; पी –

3

एक एसिंक विधि में शून्य या कार्य का रिटर्न प्रकार हो सकता है। यदि रिटर्न टाइप शून्य नहीं है तो कॉलर मुख्य प्रविष्टि विधि (जिसे एसिंक चिह्नित नहीं किया जा सकता है) के अंदर .Net 4 में पेश किए गए मानक प्रतीक्षा तंत्र का उपयोग कर सकते हैं। यहाँ एक सरल उदाहरण है:

static void Main(string[] args) 
    { 
     string address = "http://api.worldbank.org/countries?format=json"; 
     Task t = LoadJsonAsync(address); 
     // do other work while loading 
     t.Wait(); 

     Console.WriteLine("Hit ENTER to exit..."); 
     Console.ReadLine(); 
    } 

    private async static Task LoadJsonAsync(string address) 
    { 
     HttpClient client = new HttpClient(); 

     HttpResponseMessage response = await client.GetAsync(address); 

     // Check that response was successful or throw exception 
     response.EnsureSuccessStatusCode(); 

     // Read response asynchronously as JsonValue and write out top facts for each country 
     JsonArray readTask = await response.Content.ReadAsAsync<JsonArray>(); 
     Console.WriteLine("First 50 countries listed by The World Bank..."); 
     foreach (var country in readTask[1]) 
     { 
      Console.WriteLine(" {0}, Capital: {1}", 
       country.Value["name"], 
       country.Value["capitalCity"]); 
     } 

    } 
+23

मुझे नफरत है कि हर कोई हमेशा क्लाइंट का उपयोग कैसे करता है। उदाहरण के रूप में GETAsync। पोस्टर शायद किसी और की एसिंक विधि का उपयोग कैसे करें जानता है। आप कैसे * लिखते हैं * एक ?? (उदाहरण के लिए स्लीप उदाहरण का उपयोग कर) – Jeff

+0

क्या होगा यदि आपका एसिंक कार्य परिणाम देता है? कॉलिंग task.wait एक बूलियन देता है। आप प्रतीक्षा के बारे में और फिर लौटे परिणाम का उपयोग कैसे करेंगे? संपादित करें: कभी भी ध्यान न दें। 'Task.Result'। – Kyle

+0

सुनिश्चित नहीं है, लेकिन इसके लिए प्रतीक्षा() - आईएनजी से पहले टास्क टी शुरू करने की आवश्यकता नहीं है? 'T.Start(); t.Wait(); ' – Prokurors

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