PrevTask.Wait () टास्कविथ (टास्क लाइब्रेरी से) के साथ उपयोग करने की सिफारिश की गई है?


88

इसलिए मुझे हाल ही में बताया गया था कि मैं कैसे अपना उपयोग कर रहा था। टास्क के लिए कॉन्ट्यूविथ उन्हें इस्तेमाल करने का उचित तरीका नहीं था। मुझे अभी तक इसका सबूत इंटरनेट पर नहीं मिला है इसलिए मैं आप लोगों से पूछूंगा और देखूंगा कि इसका जवाब क्या है। यहाँ मैं कैसे उपयोग का एक उदाहरण है।

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 3");
    });
}

अब मुझे पता है कि यह एक सरल उदाहरण है और यह बहुत तेजी से चलेगा, लेकिन यह मान लें कि प्रत्येक कार्य कुछ लंबा ऑपरेशन करता है। तो, जो मुझे बताया गया था कि .ContinueWith में, आपको prevTask.Wait () कहना होगा; अन्यथा आप पिछले कार्य समाप्त होने से पहले काम कर सकते थे। क्या यह भी संभव है? मैंने मान लिया कि मेरा दूसरा और तीसरा कार्य केवल एक बार उनके पिछले कार्य के पूरा होने के बाद ही चलेगा।

मुझे बताया गया था कि कोड कैसे लिखें:

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 3");
    });
}

2
StartNew का प्रयोग न करें blog.stephencleary.com/2013/08/startnew-is-dangerous.html
क्रिस Marisic

जवाबों:


115

एह ... .... मुझे लगता है कि कुछ मौजूदा उत्तर कुछ याद कर रहे हैं: अपवादों के साथ क्या होता है?

एकमात्र कारण जिसे आप Waitएक निरंतरता में कहेंगे वह निरंतरता में पूर्ववर्ती से एक संभावित अपवाद का निरीक्षण करना होगा। यदि आप एक्सेस करते हैं तो वही अवलोकन होगाResultTask<T>यदि आप मैन्युअल रूप से और Exceptionसंपत्ति का उपयोग करते हैं , तो आप के मामले में भी । सच कहूं, तो मैं फोन Waitया एक्सेस नहीं करूंगा Resultक्योंकि अगर कोई अपवाद है तो आप इसे फिर से बढ़ाने की कीमत चुकाएंगे जो अनावश्यक ओवरहेड है। इसके बजाय आप बस IsFaultedसंपत्ति को रोकने के लिए जाँच कर सकते हैं Task। वैकल्पिक रूप से आप कई सिबलिंग निरंतरता का पीछा करके कांटे के वर्कफ्लो बना सकते हैं जो केवल सफलता या विफलता के आधार पर आग लगाते हैं TaskContinuationOptions.OnlyOnRanToCompletionऔर TaskContinuationOptions.OnlyOnFaulted

अब, निरंतरता में पूर्ववर्ती के अपवाद का निरीक्षण करना आवश्यक नहीं है, लेकिन आप अपने वर्कफ़्लो को आगे बढ़ने के लिए नहीं कह सकते हैं, अगर कहते हैं, "चरण 1" विफल रहा। उस स्थिति में: TaskContinuationOptions.NotOnFaultedआपकी ContinueWithकॉलों को निर्दिष्ट करने से निरंतर तर्क को कभी भी फायरिंग से रोका जा सकेगा।

ध्यान रखें कि, यदि आपकी खुद की निरंतरता अपवाद का निरीक्षण नहीं करती है, तो जो व्यक्ति इस समग्र वर्कफ़्लो को पूरा करने के लिए इंतजार कर रहा है वह इसे देखने वाला है। या तो वे अपस्ट्रीम Waitपर हैं और Taskयह पूरा होने पर अपने स्वयं के निरंतरता से निपटने के लिए। यदि यह बाद का है, तो उनकी निरंतरता को पूर्वोक्त अवलोकन तर्क का उपयोग करना होगा।


2
अंत में कोई सही उत्तर दे। @ Travyguy9 कृपया इस @DrewMarsh उत्तर को पढ़ें और इसके बारे में अधिक पढ़ेंTaskContinuationOptions
जैस्पर

2
महान जवाब, मैं "ध्यान रखें कि, यदि आपकी खुद की निरंतरता अपवाद का निरीक्षण नहीं करती है, तो जो व्यक्ति इस समग्र वर्कफ़्लो को पूरा करने के लिए इंतजार कर रहा है, वह इसका अवलोकन करेगा।" हालांकि एक सवाल यह है कि जब आपके कार्य का इंतजार नहीं किया जाता है, तो डिफ़ॉल्ट वेटर कौन है? (इसका उत्तर नहीं मिल सका)
थिबॉल्ट डी।

20

आप इसका सही उपयोग कर रहे हैं।

एक निरंतरता बनाता है जो लक्ष्य टास्क के पूरा होने पर अतुल्यकालिक रूप से निष्पादित होता है।

स्रोत: टास्क.कंटू विधि (MSDN के रूप में कार्रवाई)

prevTask.Wait()हर Task.ContinueWithआह्वान में कॉल करने के लिए अनावश्यक तर्क को दोहराने का एक अजीब तरीका लगता है - यानी "सुपर डुपर निश्चित" होने के लिए कुछ करना क्योंकि आप वास्तव में यह नहीं समझते हैं कि कोड का एक निश्चित बिट क्या करता है। एक नल के लिए जाँच की तरह सिर्फ एक फेंक करने के लिएArgumentNullException जहाँ यह वैसे भी फेंक दिया गया था।

तो, नहीं, जिसने भी आपको बताया है कि वह गलत है और शायद समझ में नहीं आता कि क्यों Task.ContinueWithमौजूद है।


16

किसने कहा तुमसे ये?

MSDN का हवाला देते हुए :

एक निरंतरता बनाता है जो लक्ष्य टास्क के पूरा होने पर अतुल्यकालिक रूप से निष्पादित होता है।

इसके अलावा, जारी रखने का उद्देश्य क्या होगा यह पिछले कार्य के लिए इंतजार नहीं कर रहा था, तो पूरा हो जाने की साथ?

आप इसे स्वयं भी परख सकते हैं:

Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
        Thread.Sleep(2000);
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("I waited step 1 to be completed!");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 3");
    });

5

से MSDN परTask.Continuewith

जब तक मौजूदा कार्य पूरा नहीं हो जाता है, तब तक दिए गए कार्य को निष्पादन के लिए निर्धारित नहीं किया जाएगा। यदि निरंतरता पैरामीटर के माध्यम से निर्दिष्ट मानदंड पूरे नहीं किए जाते हैं, तो अनुसूचित के बजाय निरंतरता कार्य रद्द कर दिया जाएगा।

मुझे लगता है कि जिस तरह से आप पहले उदाहरण में काम करने की उम्मीद करते हैं वह सही तरीका है।


2

आप टास्क के बजाय टास्क का उपयोग करने पर भी विचार कर सकते हैं।

स्टीफन क्लीरी के ब्लॉग पोस्ट और स्टीफन टूब के पोस्ट के संदर्भ में वे मतभेदों की व्याख्या करते हैं। इस उत्तर में एक चर्चा भी है ।


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

0

प्रवेश करके Task.Resultआप वास्तव में इसी तरह के तर्क कर रहे हैंtask.wait


हाँ। हम प्रतीक्षा () विधि से बच सकते हैं। लेकिन यह केवल परिणाम कार्यों के साथ काम करता है, जैसे कार्य <bool>
अलेक्जेंडर उलमास्कुलोव

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

0

मैं दोहराऊंगा कि बहुतों ने पहले ही क्या बोल दिया है, prevTask.Wait() अनावश्यक है

अधिक उदाहरणों के लिए, एक निरंतर कार्य का उपयोग करके चेनिंग टास्क में जा सकता है , फिर भी माइक्रोसॉफ्ट द्वारा एक और लिंक अच्छे उदाहरणों के साथ।

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