2012-09-14 22 views
5

कोड को असीमित रूप से चलाने के लिए (जैसे async/प्रतीक्षा के साथ) मुझे उचित कार्य की आवश्यकता है। निस्संदेह ढांचे में कई पूर्वनिर्धारित विधियां हैं जो सबसे अधिक लगातार संचालन को कवर करती हैं, लेकिन कभी-कभी मैं अपने स्वयं के लिखना चाहता हूं। मैं सी # के लिए नया हूं इसलिए यह काफी संभव है कि मैं इसे गलत कर रहा हूं लेकिन मैं कम से कम अपने वर्तमान अभ्यास से पूरी तरह से खुश नहीं हूं। मैं क्या कर रहा हूँ के लिए निम्नलिखित उदाहरण देखें:कस्टम कार्य वापसी विधि को सही तरीके से लिखने के लिए कैसे करें

public async Task<bool> doHeavyWork() 
    { 
     var b1 = await this.Foo(); 
     //var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run 
     var b2 = await Task.Run(()=>Bar()); 
     return b1 & b2; 
    } 

public Task<bool> Foo() 
    { 
     return Task.Factory.StartNew(() => 
            { 
             //do a lot of work without awaiting 
             //any other Task 
             return false; 
            }); 
    } 

public bool Bar() 
    { 
     //do a lot of work without awaiting any other task 
     return false; 
    } 

सामान्य मैं बनाने में और फू उदाहरण की तरह इस तरह के तरीकों का उपभोग, लेकिन वहाँ एक 'अतिरिक्त' लैम्ब्डा पूरे विधि तर्क जो नहीं दिखता है युक्त बहुत सुंदर imho। एक और विकल्प बार उदाहरण की तरह किसी भी विधि का उपभोग करना है, हालांकि मुझे लगता है कि यह भी बदतर है क्योंकि यह स्पष्ट नहीं है कि इस विधि को एसिंक (उचित विधि नामों के अलावा BarAsync) और टास्क.फैक्टरी.स्टार्टन्यू को भी चलाना चाहिए कार्यक्रम में कई बार दोहराया जाना चाहिए। मुझे नहीं पता कि कंपाइलर को कैसे बताना है कि यह विधि एक कार्य देता है, कृपया इसे पूरी तरह से एक कार्य में लपेटें जब 'जिसे मैं करना चाहता हूं।

अंत में मेरा प्रश्न: ऐसी विधि लिखने का सबसे अच्छा तरीका क्या है? क्या मैं 'अतिरिक्त' लैम्ब्डा से छुटकारा पा सकता हूं (बिना अतिरिक्त नामित विधि जोड़कर)?

EDIT जैसा कि सर्वि ने कहा कि विधि का एक तुल्यकालिक संस्करण हमेशा अच्छा कारण है। एक async संस्करण केवल तभी प्रदान किया जाना चाहिए जब निरपेक्ष आवश्यक (स्टीफन क्लेरी का लिंक)।

+0

'" पाठ्यक्रम के अतिरिक्त नामित विधि को जोड़ने के बिना "'एक विकल्प के रूप में इसे अस्वीकार क्यों करें? 'सार्वजनिक बूल बार' और 'सार्वजनिक कार्य बारएसिंक' बनाएं। – Servy

+0

मैं ओवरहेड से बचना चाहता था। यदि किसी विधि को सिंक्रोनस या असिंक्रोनस का उपयोग करना समझ में आता है तो यह ठीक होगा। यदि नहीं, तो सार्वजनिक बारएसिंक और एक निजी बार (इसे छिपाने के लिए) होगा और इस मामले में मुझे इसके लिए बहुत अधिक कारण नहीं दिख रहा है। – marce

उत्तर

3

अगर कोई नया थ्रेड/टास्क में शुरू किए बिना Bar पर कॉल करना चाहता है तो क्या दुनिया खत्म हो जाएगी? क्या होगा यदि कोई अन्य विधि है जो पहले से ही पृष्ठभूमि थ्रेड में है, तो उसे लंबे समय तक चलने वाले कोड को चलाने के लिए एक नया कार्य शुरू करने की आवश्यकता नहीं है? क्या होगा यदि विधि क्लास लाइब्रेरी में दोबारा काम किया जा रहा है जिसे डेस्कटॉप ऐप संदर्भ के साथ-साथ एएसपी या कंसोल संदर्भ दोनों से भी बुलाया जाता है? उन अन्य संदर्भों में कि विधि को शायद सीधे चलाने की आवश्यकता होगी, Task के रूप में नहीं।

मैं कहूंगा कि आपका कोड Bar जैसा दिखना चाहिए, जब तक कि यह बिल्कुल अनिवार्य नहीं है कि, किसी भी परिस्थिति में, क्या यह कोड Task शुरू किए बिना चलाया जाना चाहिए।

यह भी ध्यान रखें कि .NET के नए संस्करणों के साथ आपको Task.Factory.StartNew से Task.Run पर स्विच करना चाहिए, इसलिए कोड की मात्रा नीचे जाना चाहिए (एक टैड)।

+1

ठीक है, आपका अंक मिला। तो कोई 'टास्क' में इस विधि को बल नहीं देता है क्योंकि यह आमतौर पर एक बुरा विचार है :) और कार्य के लिए धन्यवाद। रुन संकेत, मैंने इसे किसी भी तरह से याद किया ... – marce

+3

यह भी देखें: [क्या मुझे सिंक्रोनस विधियों के लिए एसिंक्रोनस रैपर का पर्दाफाश करना चाहिए? ] (http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) –