टास्क के लिए क्या उपयोग है। Cromultult <TResult> C # में


189

C # और TPL ( टास्क पैरेलल लाइब्रेरी ) में, Taskक्लास एक चल रहे काम का प्रतिनिधित्व करता है जो टाइप T का मान पैदा करता है।

मैं जानना चाहूंगा कि Task.FromResult पद्धति की क्या आवश्यकता है ?

वह है: ऐसे परिदृश्य में जहां आपके पास पहले से ही उत्पादित मूल्य है, इसे वापस टास्क में लपेटने की क्या आवश्यकता है?

केवल एक चीज जो ध्यान में आती है, वह यह है कि टास्क उदाहरण को स्वीकार करने वाले अन्य तरीकों के लिए कुछ एडेप्टर के रूप में इसका उपयोग किया जाता है।


4
क्या यह आपकी मदद करता है? msdn.microsoft.com/en-us/library/hh228607.aspx
इज़िकॉन

30
कुछ हद तक मैं इससे सहमत हूं, लेकिन इस तरह के घने, उपयोगी, समेकित, डिस्कशन-उन्मुख पृष्ठों का निर्माण एक बहुत बड़ा लाभ है। मैं लगभग हमेशा एक अच्छे, घने स्टैकओवरफ्लो पेज से अधिक से अधिक सीखता हूं, और कई स्थानों पर शोध कर रहा हूं, इसलिए इस मामले में, मुझे खुशी है कि उसने यह पोस्ट किया है।
एलेक्स एडेलस्टीन

41
मुझे लगता है कि Google मुझे SO पर लाता है और SO मुझे Google पर जाने के लिए कहता है। यह एक परिपत्र संदर्भ है :)
जीमेल उपयोगकर्ता

जवाबों:


258

मेरे द्वारा उपयोग किए गए दो सामान्य मामले हैं:

  1. जब आप एक इंटरफ़ेस लागू कर रहे हैं जो अतुल्यकालिक कॉलर्स की अनुमति देता है, लेकिन आपका कार्यान्वयन तुल्यकालिक है।
  2. जब आप परीक्षण के लिए अतुल्यकालिक कोड को स्टबिंग / मॉकिंग कर रहे हों।

6
# 1 के लिए एक अच्छा मामला एक वेब सेवा है। आपके पास एक समकालिक सेवा पद्धति हो सकती है जो वापस आती है Task.FromResultऔर एक ग्राहक जो I / O नेटवर्क के लिए अतुल्यकालिक रूप से प्रतीक्षा करता है। इस तरह से आप क्लाइंट / सर्वर के बीच समान इंटरफ़ेस का उपयोग कर साझा कर सकते हैं ChannelFactory
नेल्सन रॉदरमेल

2
उदाहरण के लिए ChallengeAsync विधि। डब्ल्यूटीएफ एमएस सोच के डिजाइनर थे? टास्क को वापस करने के इस तरीके का कोई कारण नहीं है। और एमएस से सभी नमूना कोड बस FromResult (0) है। उम्मीद है कि कंपाइलर इस दूर का अनुकूलन करने के लिए पर्याप्त स्मार्ट है, और वास्तव में एक नया धागा नहीं है और फिर इसे तुरंत मार!
जॉन हेनकेल

14
@ जॉन्हेनकेल: ओविन को जमीन से डिज़ाइन किया गया है जो कि एसिंक्स-फ्रेंडली है। Interfaces और Base Classes अक्सर Async हस्ताक्षरों का उपयोग करते हैं क्योंकि यह सिर्फ async होने की अनुमति देता है ( बल नहीं )। तो यह IEnumerable<T>व्युत्पन्न करने के समान है IDisposable- यह असंख्य को डिस्पोजेबल संसाधनों की अनुमति देता है, न कि इसे करने के लिए मजबूर करता है। न तो FromResult, asyncऔर न ही awaitथ्रेड्स थूकेंगे।
स्टीफन क्लीरी

4
@StephenCleary hmhm, यह समझाने के लिए धन्यवाद। मैंने मान लिया था कि इंतजार होगा, लेकिन मैंने कोशिश की और मैंने देखा कि यह नहीं है। केवल टास्क.रूण करता है। इसलिए, x = टास्क का इंतजार करें ।romResult (0); x = 0 कहने के बराबर है; यह भ्रमित करने वाला है, लेकिन अच्छा है!
जॉन हेनकेल

4
@ ओली: आई / ओ संचालन के लिए, सबसे अच्छा समाधान यह है कि इसे अतुल्यकालिक रूप से लागू किया जाए, लेकिन कभी-कभी आपके पास यह विकल्प नहीं होता है। इसके अलावा, कभी-कभी आप इसे तुल्यकालिक रूप से लागू कर सकते हैं (उदाहरण के लिए, एक कैश्ड परिणाम, एक अतुल्यकालिक कार्यान्वयन पर वापस गिरना यदि मूल्य संचित नहीं है)। आम तौर पर, एक Task-पूर्ण विधि का अर्थ है " अतुल्यकालिक हो सकता है"। तो कभी-कभी विधियों को एक अतुल्यकालिक हस्ताक्षर दिया जाता है जो पूरी तरह से जानता है कि कुछ कार्यान्वयन तुल्यकालिक होंगे (जैसे, NetworkStreamasync होना चाहिए, लेकिन MemoryStreamसिंक होना चाहिए)।
स्टीफन क्लीयर

50

एक उदाहरण एक विधि होगी जो कैश का उपयोग करती है। यदि परिणाम पहले से ही संगणित है, तो आप पूर्ण कार्य को मान के साथ लौटा सकते हैं (उपयोग करके Task.FromResult)। यदि यह नहीं है, तो आप आगे बढ़ते हैं और चल रहे काम का प्रतिनिधित्व करते हुए एक काम वापस करते हैं।

कैश उदाहरण: कैश उदाहरण प्री-कंप्यूटेड मानों के लिए Task.FromResult का उपयोग करते हुए


और पूर्ण कार्य, जैसे कि वापस लौटे Task.FromResult, को कैश किया जा सकता है।
पाउलो मोरागडो

1
@Paulo: संपूर्ण टास्क ऑब्जेक्ट को स्मृति में रखने से सिर्फ परिणाम कैशिंग की तुलना में अधिक बेकार लगता है।
बेन वोइगट

2
"मूल्य कार्यों" की अपेक्षा पहले से ही कैश की गई है। मैं वास्तव में कौन सा याद नहीं है, लेकिन मुझे लगता है कि Task.FromResult(0), Task.FromResult(1), Task.FromResult(false)और Task.FromResult(true)कैश नहीं किया जाता। आप नेटवर्क एक्सेस के लिए किसी कार्य को कैश नहीं करना चाहते हैं, लेकिन परिणाम में से एक पूरी तरह से ठीक है। क्या आप मूल्य वापस करने के लिए हर बार एक को बनाना पसंद करेंगे?
पाउलो मोरागडो

4
... और मेरे अपने प्रश्न का उत्तर देने के लिए, कैश ऑफ़ टास्क का लाभ यह है कि उनमें से कुछ को पूरा किया जा सकता है, और अन्य वे हो सकते हैं जो अभी तक समाप्त नहीं हुए हैं। कॉल करने वालों को देखभाल करने की आवश्यकता नहीं है: वे एक एसिंक्रोनस कॉल करते हैं, और यदि यह पहले से ही पूरा हो गया है, तो उन्हें प्रतीक्षा करने पर तुरंत उत्तर मिलता है, यदि नहीं, तो वे बाद में प्राप्त करते हैं। इन कैश्ड कार्यों के बिना, या तो (ए) को दो अलग-अलग तंत्रों की आवश्यकता होगी, एक सिंक और एक एसिंक्स - कॉलर के लिए बोझिल, या (बी) को गतिशील रूप से एक टास्क बनाना होगा, हर बार एक कॉलर एक जवाब के लिए पूछता है जो पहले से ही उपलब्ध है (यदि हमने केवल एक TResult को कैश किया था)।
ToolmakerSteve

1
मुझे ये अब मिला। जवाब का शब्द थोड़ा उलझा हुआ था। टास्क में ही "कैशिंग" तंत्र नहीं है। लेकिन अगर आपने ... के लिए एक कैशिंग मैकेनिज्म लिखा है ... फ़ाइलों को डाउनलोड करते हुए, टास्क <File> GetFileAync (), आप तुरंत एक फ़ाइल लौटा सकते हैं जो पहले से कैश में है। Task.FromResult (कैश्ड फ़ाइल), और वेट थ्रेड स्विच न होने से समय की बचत के साथ समकालिक रूप से चलेगा।
ब्रेनवॉस्क

31

जब आप async कीवर्ड का उपयोग किए बिना प्रतीक्षा करने योग्य विधि बनाना चाहते हैं, तो इसका उपयोग करें। मुझे यह उदाहरण मिला:

public class TextResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;

    public TextResult(string value, HttpRequestMessage request)
    {
        _value = value;
        _request = request;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        return Task.FromResult(response);
    }
}

यहाँ आप IHttpActionResult इंटरफ़ेस के अपने कार्यान्वयन को वेब एपि एक्शन में उपयोग करने के लिए बना रहे हैं। ExecuteAsync विधि अतुल्यकालिक होने की उम्मीद है, लेकिन आपको इसे अतुल्यकालिक और प्रतीक्षा योग्य बनाने के लिए async कीवर्ड का उपयोग करने की आवश्यकता नहीं है। चूँकि आपके पास पहले से ही परिणाम है और आपको Task.FromResult का उपयोग करने के लिए बेहतर कुछ भी इंतजार करने की आवश्यकता नहीं है।


20

MSDN से:

यह विधि तब उपयोगी होती है जब आप एक अतुल्यकालिक ऑपरेशन करते हैं जो एक टास्क ऑब्जेक्ट को लौटाता है, और उस टास्क ऑब्जेक्ट का परिणाम पहले से ही गणना किया जाता है।

http://msdn.microsoft.com/en-us/library/hh228607.aspx


4

जब आप एक एसिंक्रोनस ऑपरेशन करना चाहते हैं, तो Task.FromResult का उपयोग करें, लेकिन कभी-कभी परिणाम हाथ में सिंक्रोनाइज़ होता है। आप यहाँ एक अच्छा नमूना देख सकते हैं http://msdn.microsoft.com/en-us/library/hh228607.aspx


आपके अच्छे नमूने में, परिणाम समकालिक रूप से हाथ में नहीं है, ऑपरेशन सभी async हैं, Task.FromResultइसका उपयोग पहले से कैन्ड किए गए सिंक परिणाम प्राप्त करने के लिए किया जाता है।
रॉड्रिगो रीस

1

मेरा तर्क है कि आप टास्क का उपयोग कर सकते हैं। फ़्रीऑनकल्चर उन तरीकों के लिए जो तुल्यकालिक हैं जो आपके कोड में अन्य स्वतंत्र काम करने के लिए पूरा करने में लंबा समय लेते हैं। आईडी के बजाय उन तरीकों को बनाने के लिए हालांकि async कहते हैं। लेकिन उस स्थिति की कल्पना करें जहां आपके पास नामक कोड पर कोई नियंत्रण नहीं है और आप चाहते हैं कि अंतर्निहित समानांतर प्रसंस्करण।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.