6

मैं हाल ही में कुछ स्थितियों में आया हूं जहां async विधियां सिंक्रनाइज़ेशन निष्पादित करती हैं, लेकिन फिर भी कार्य वापस करें, इसलिए उनका इंतजार किया जा सकता है, उदा।कार्य। FromResult() बनाम टास्क.रुन()

public virtual Task CreateAsync(TUser user) 
{ 
    ThrowIfDisposed(); 
    if (user == null) throw new ArgumentNullException("user"); 
    Context.Save(user); 
    Context.Flush(); 
    return Task.FromResult(0); 
} 

निश्चित रूप से यह एक धागा करने के लिए शायद-लंबे समय से चल आपरेशन प्रेषण और अभी भी सक्रिय कार्य वापस जाने के लिए बेहतर है, सही मायने में बहुप्रतीक्षित जा करने के लिए:

public virtual Task CreateAsync(TUser user) 
{ 
    ThrowIfDisposed(); 
    if (user == null) throw new ArgumentNullException("user"); 
    return Task.Run(() => 
    { 
     Context.Save(user); 
     Context.Flush(); 
    }); 
} 

मैं कुछ संदेह है, हालांकि, कि बस टीपीएल धागे को कताई करना सबसे सुरक्षित अभ्यास नहीं है। इन दो अलग-अलग पैटर्न पर कोई टिप्पणी?

+0

जब संभव हो, तो आपको इनमें से किसी एक के बजाय वास्तविक एसिंक विधि को कॉल करना चाहिए। – SLaks

+0

@SLaks दूसरा तरीका एसिंक नहीं है (एक नया कीवर्ड नहीं उपयोग करने के अलावा)? (किसी ऐसे व्यक्ति से आ रहा है जो अक्सर एसिंक सुविधाओं का उपयोग नहीं करता) –

+0

@KyleW: यह अभी भी एक धागा बर्बाद कर देता है। Http://blog.slaks.net/2014-12-23/parallelism-async-threading-explained/ – SLaks

उत्तर

10

यदि आपकी विधि तुल्यकालिक है तो आपको Task से शुरू करने के लिए वापस नहीं करना चाहिए। बस एक पारंपरिक सिंक्रोनस विधि बनाएँ।

किसी कारण ऐसा संभव नहीं है के लिए (उदाहरण के लिए, यदि आप कुछ async इंटरफ़ेस को लागू) यदि इस मामले Task.CompletedTask में Task.FromResult या और भी बेहतर उपयोग कर एक पूर्ण कार्य लौटने (.NET 4.6 में जोड़ा) कार्यान्वयन में Task.Run का उपयोग कर की तुलना में बेहतर है :

public virtual Task CreateAsync(TUser user) 
{ 
    // ... 
    return Task.CompletedTask; 
} 

अपने एपीआई के उपभोक्ता के बारे में Task -returning विधि तुल्यकालिक नहीं चल रहा दृढ़ता से परवाह करता है अगर वे Task.Run खुद को का उपयोग सुनिश्चित करने के लिए कर सकते हैं।

आपको यह ध्यान में रखना चाहिए कि एसिंक तरीकों में पहले से सिंक्रोनस भाग (पहले इंतजार से पहले हिस्सा) हो सकता है भले ही वे अंततः अतुल्यकालिक रूप से जारी रखें। आप एसिंक विधियों को तुरंत Task वापस नहीं देख सकते हैं।

5

Task.FromResult वास्तव में कोई काम नहीं करता या चलाता है लेकिन यह केवल कार्य ऑब्जेक्ट में लौटा हुआ परिणाम लपेटता है। मैंने व्यक्तिगत रूप से इसे Unit Tests में उपयोग किया जहां मुझे Async विधियों का अनुकरण करने की आवश्यकता है और निश्चित रूप से मैं यूनिट परीक्षणों में वास्तविक कार्य नहीं करना चाहता हूं।

Task.Run के अलावा वास्तव में एक कार्य बना देगा और टास्कशेड्यूलर पर एक कार्य चलाएगा। Async प्रोग्रामिंग करते समय Task.Run का उपयोग करने की अनुशंसा नहीं की जाती है। इसके बजाय कार्यों पर await का उपयोग करें। स्टीफन क्लेरी द्वारा कुछ do's and don't of Tasks देखें।

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