2012-07-17 16 views
9

निम्न विधि को देखते हुए:का इंतजार AsyncMethod() बनाम इंतजार इंतजार Task.Factory.StartNew <TResult> (AsyncMethod)

public async void SomeEventHandler(EventArgs args) { 
    var myObject = await await Task.Factory.StartNew<Task<MyObject>>(DoSomethingAsync); 
    // do something with myObject 
} 

और:

public async void SomeEventHandler(EventArgs args) { 
    var myObject = await DoSomethingAsync(); 
    // do something with myObject 
} 

public async Task<MyObject> DoSomethingAsync() { 
    // do some work 
    await OpenSomeFileAsync(); 
    return new MyObject(); 
} 

वहाँ के बीच एक अंतर है

मैं सोच रहा था कि DoSomethingAsync का "कुछ काम करें" भाग तुरंत एक नए कार्य में होगा पहला मामला, लेकिन ईमानदार होने के लिए मैं वास्तव में पूरी तरह से समझ नहीं पा रहा हूं कि कार्य, एसिंक और प्रतीक्षा कैसे काम कर रहे हैं, और मुझे पूरा यकीन है कि मैं अपने लिए चीजों को अधिक जटिल बना रहा हूं।

संपादित करें:

इस सवाल के बारे में इस मेट्रो उदाहरण को देख से आया था:

var unused = Task.Factory.StartNew(async() => { // some work... }); 
// unused is of type Task<TResult> 

मैं करने के लिए कोशिश कर रहा था: MainPage.xaml.cs में विशेष रूप से http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782

, वे इस राशि एक अज्ञात एसिंक फ़ंक्शन का उपयोग किए बिना इसे पुन: कार्य करें और मैंने सोचना शुरू किया, क्यों न केवल एक एसिंक विधि लिखना और इसे प्रतीक्षा करना, StartNew को कॉल करने और एसिंक फ़ंक्शन में सौंपने के बजाय?

+0

आप इसे इस तरह से लिखने के लिए क्यों चाहिए? नए 'async' /' await' कीवर्ड का उपयोग करने का पूरा बिंदु इतना था कि आपको यह नहीं करना था। –

+0

कोड ऑफ-हाथ –

+0

के खराब उदाहरण टुकड़े की तरह लगता है मैंने अभी खुद को देखा, और ... वाह। हाँ, वह "आधिकारिक विंडोज एसडीके नमूना" कोड ** वास्तव में बुरा ** है! मुझे लगता है कि वे 'async' के बिंदु को पूरी तरह से याद करने में कामयाब रहे हैं! –

उत्तर

11

अधिकांश समय, Task जोड़ना उपयोगी नहीं है, लेकिन कुछ मामलों में, यह हो सकता है।

अंतर नहीं है अगर आप यूआई धागा (या कुछ इसी तरह) पर हैं और सीधे DoSomethingAsync() निष्पादित, इसके पहले भाग (// do some work) भी यूआई धागे पर निष्पादित करेगा, और इसलिए होगा विधि के किसी भी निरंतरता भागों (जब तक वे ConfigureAwait() का उपयोग करते हैं)। दूसरी ओर, यदि आप एक और Task शुरू करते हैं, तो पहले भाग और DoSomethingAsync() के किसी भी निम्नलिखित भाग ThreadPool पर निष्पादित होंगे।

तो DoSomethingAsync() सही ढंग से लिखा है, जोड़ने एक और Task आप किसी भी लाभ नहीं देना चाहिए (और आप अधिक भूमि के ऊपर का नुकसान दे देंगे), लेकिन मैं कल्पना कर सकते हैं कि ऐसी स्थितियां यह एक फर्क कर सकते हैं।

इसके अलावा, Task.Factory.StartNew() और दो await रों उपयोग करने के बजाय, आप लिख सकते हैं:

await Task.Run(DoSomethingAsync); 
+1

अच्छा बिंदु, मैंने प्रतीक्षा से पहले भाग के बारे में नहीं सोचा था ... +1 –

+0

बहुत अच्छा जवाब, प्रतिक्रिया के लिए सभी को धन्यवाद! –

4

हां, एक अंतर है: पहले रूप में, आपके पास कार्य का एक अतिरिक्त स्तर है, जो बिल्कुल कुछ भी उपयोगी नहीं लाता है।

प्रथम रूप मूल रूप से इस के बराबर है:

Task<Task<MyObject>> task1 = Task.Factory.StartNew<Task<MyObject>>(DoSomethingAsync); 
Task<MyObject>> task2 = await task1; 
var myObject = await task2; 

तो यह वास्तव में मतलब नहीं है: यदि आप एक काम है कि बस ... बनाता है किसी अन्य कार्य बना रहे हैं।

+0

प्रतिक्रिया के लिए धन्यवाद - मैं बहुत सोच रहा था।यदि आपके पास एक पल है तो क्या आप मेरे संपादन को संबोधित कर सकते हैं? मैं उदाहरण में देखे गए दृष्टिकोण से उलझन में हूं ... –

+0

AFAICT, यह एक बुरा उदाहरण है –

+0

@justin, मैं जेम्स से सहमत हूं, यह वास्तव में एक बुरा उदाहरण है ... कोई बनाने का कोई कारण नहीं है एक async विधि पर कार्य, क्योंकि यह पहले से ही एक कार्य –

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