2012-09-03 16 views
14

अगर मैं एक सामान्य विधि है कि मैं बनाना चाहते है अतुल्यकालिक:एसिंक का उपयोग क्यों करें और कार्य <> के साथ प्रतीक्षा करें?

public int Foo(){} 

मुझे क्या करना होगा:

public Task<int> FooAsync(){ 
    return Task.Run(() => Foo()); 
} 

मैं क्यों करना होगा:

public async Task<int> FooAsync(){ 
    return await Task.Run(() => Foo()); 
} 

तरह से मैं करने की योजना इसका उपयोग करें:

FooAsync().ContinueWith((res) => {}); 

मैं चाहता हूं कि बिना किसी रोक के चलने की विधि, लेकिन मुझे कॉलबैक की तरह कुछ चाहिए, इसलिए ContinueWith। लेकिन दूसरे संस्करण के साथ, इसका उपयोग करने के लिए एक बिंदु है?

उत्तर

14

मेरी समझ में, आप केवल async और await की जरूरत है जब आप एक तरीका है जिसके कुछ async अंदर कॉल करता है लिखते हैं, लेकिन आप इसे नज़र चाहते हैं जैसे कि यह नहीं करता है। दूसरे शब्दों में आप कोड लिखना और पढ़ना चाहते हैं जैसे कि यह कुछ सामान्य अनुक्रमिक कोड था, अपवादों को संभालें जैसे कि यह सामान्य अनुक्रमिक कोड था, मूल्यों को वापस लौटाएं जैसे कि यह सामान्य क्रमिक कोड था और इसी तरह। फिर कंपाइलर की ज़िम्मेदारी तर्क को संरक्षित करने वाले सभी आवश्यक कॉलबैक के साथ उस कोड को फिर से लिखना है।

आपकी विधि इतनी सरल है कि मुझे नहीं लगता कि इसे फिर से लिखना आवश्यक है, आप केवल कार्य वापस कर सकते हैं, लेकिन जो भी इसे उपभोग करता है, वह await अपने रिटर्न वैल्यू के लिए कर सकता है।

+0

उत्कृष्ट विवरण! – paulsm4

+0

धन्यवाद, @ paulsm4। मुझे यह कहना होगा कि मैंने हाल ही में जो कुछ सुना है, उसे मैं फिर से देख रहा हूं, मुझे लगता है कि यह http://hanselminutes.com/327/everything-net-programmers-now-about-asynchronous-programming-is-wrong से है, लेकिन 100% निश्चित नहीं है। मुझे अभी तक एसिंक फीचर के साथ ज्यादा अनुभव नहीं था, इसलिए मैं गलत हो सकता हूं और मुझे और जानने में खुशी होगी, शायद इस मामले में एसिंक कुछ लाभ प्रदान करता है। –

+2

इसके अतिरिक्त, आप पढ़ना चाहेंगे [क्या मुझे सिंक्रोनस विधियों के लिए एसिंक्रोनस रैपर का खुलासा करना चाहिए?] (Http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) (उत्तर यदि आपके पास सिंक्रोनस विधि है, तो लगभग हमेशा "नहीं;" है, फिर इसे एक सिंक्रोनस विधि हस्ताक्षर दें)। –

5

मैं क्यों करना होगा:

public async Task<int> FooAsync() 
{ 
    return await Task.Run(() => Foo()); 
} 

आप नहीं होगा। आपका पिछला संस्करण कार्य लौटाता है जो पहले से ही प्रतीक्षा कर रहा है। यह नया संस्करण कुछ भी नहीं जोड़ता है।

तरह से मैं इस का उपयोग करने की योजना है:

FooAsync().ContinueWith((res) => {}); 

मैं विधि बस को रोके बिना चलाना चाहते हैं, लेकिन मैं एक कॉलबैक की तरह कुछ निकाल दिया जा करने के लिए है, इसलिए ContinueWith चाहते हैं।

void async DoAsyncStuff() 
{ 
    int res = await FooAsync(); 
    DoSomethingWithInt(res); 
} 

: आप इस तरह एक ही कोड लिख सकते हैं

void DoAsyncStuff() 
{ 
    FooAsync().ContinueWith((res) => { DoSomethingWithInt(res.Result) }); 
} 

async का उपयोग करना:

यह जहां अंतर में आता है के अपने उदाहरण एक छोटा सा शरीर से बाहर हैं। नतीजा वही है। await कीवर्ड आपकी शेष विधि को निरंतरता में बदल देता है जो FooAsync मान उत्पन्न करने के बाद फिर से शुरू हो जाता है। यह आपके अन्य कोड की तरह है, लेकिन पढ़ने में आसान है। * शग *

+0

आपकी 'async' विधि वास्तव में' शून्य वापसी वापस मत हो। 'async' विधियों को केवल एक शून्य के लिए एक हैंडलर होने पर शून्य लौटाया जाना चाहिए। विधि में कोई वापसी मूल्य नहीं होने पर इसे 'कार्य' वापस करना चाहिए। इसके अलावा, सभ्य पर्याप्त पद। – Servy

+0

@ सर्वी "एसिंक विधियों को केवल एक घटना के लिए एक हैंडलर होने पर शून्य लौटाया जाना चाहिए।" यह मामला यहाँ है, है ना? इस उदाहरण में 'DoAsyncStuff' वापस क्या करना चाहिए, और यह अनिवार्य कोड लिखने के बिना उस मूल्य को कहां मिलेगा? साथ ही, यदि एक एसिंक विधि कार्य लौटाती है और आप * प्रतीक्षा नहीं करते हैं, तो आपको एक कंपाइलर चेतावनी (सीएस 4014) मिलती है, जो परेशान है। मैंने हाल ही में [उस मुद्दे के बारे में पूछा] (http://stackoverflow.com/questions/14903887/warning-this-call-is-not-awaited-execution-of-the-current-method-continues) यहां। यदि आपके पास बेहतर उत्तर है, तो क्या आप इसे वहां पोस्ट कर सकते हैं? – Mud

+0

जब एक 'async' विधि शून्य हो जाती है तो यह अनिवार्य रूप से इसे "आग और भूल" विधि बनाती है। जब कॉलर वास्तव में समाप्त होता है तो कॉलर को जानने का कोई तरीका नहीं है। यहां ओपी के कोड से कोई संकेत नहीं है कि वह यही चाहता है। कंपाइलर चेतावनी के लिए, ऐसा इसलिए है क्योंकि आप लगभग निश्चित रूप से * ऐसा नहीं करना चाहते हैं, जैसा कि मैंने आपको पोस्ट किए गए पोस्ट में बताया था; चेतावनी * सही * यह इंगित करती है कि आपके डिज़ाइन में कोई दोष है, और बाधाएं हैं कि आप जो व्यवहार प्राप्त कर रहे हैं उसे नहीं चाहते हैं। जबकि आप कुछ किनारे के मामलों में उस व्यवहार को चाहते हैं, मैं अपने दावे से खड़ा हूं। – Servy

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