8

सभी, वहाँ ऊपर विषय पर कई सवाल हैं, लेकिन मेरा मानना ​​है कि यह पर्याप्त रूप से एक नया सवाल वारंट अलग है। मैं निम्नलिखित Task और कार्य Status की एक किस्म से निपटने के लिए एक निरंतरता है, TaskStatus.RanToCompletion, TaskStatus.Canceled और TaskStatus.Faulted के माध्यम से निश्चित रूप से AggregateException। कोड की तरहTPL और एक्सेप्शन हैंडलिंग

Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
    asyncMethod(uiScheduler, token, someBoolean), token); 

asyncTask.ContinueWith(task => 
{ 
    // Check task status. 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.RanToCompletion: 
      if (asyncTask.Result) 
      { 
       // Do stuff... 
      } 
      break; 
     case TaskStatus.Faulted: 
      if (task.Exception != null) 
       mainForm.progressRightLabelText = task.Exception.InnerException.Message; 
      else 
       mainForm.progressRightLabelText = "Operation failed!"; 
     default: 
      break; 
    } 
} 

लग रहा है यह सब अच्छी तरह से काम करता है, लेकिन मैं चिंतित है या नहीं, मैं यह सही कर रहा हूँ कर रहा हूँ, के रूप में वहाँ एक AggregateException की संभावना है निरंतरता के भीतर से फेंक दिया जा रहा है - फिर क्या?

मैं अपने asyncTask पर Wait नहीं चाहता हूं और न ही निरंतरता के रूप में यह यूआई थ्रेड पर वापसी को अवरुद्ध कर देगा। एक निरंतरता के भीतर से फेंक दिया किसी भी अपवाद को पकड़ने के लिए इसका मतलब यह नहीं कर सकते हैं मैं इस तरह कुछ करने के लिए निश्चित रूप से

Task parentTask = Task.Factory.startNew(() => 
    { 
     Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
      asyncMethod(uiScheduler, token, someBoolean), token); 

     Task continueTask = asyncTask.ContinueWith(task => 
      { 
       // My continuation stuff... 
      } 

     try 
     { 
      continueTask.Wait(); 
     } 
     catch(AggregateException aggEx) 
     { 
      // Some handling here... 
     } 
    }); 

यह और भी काम करेगा? यहाँ सबसे अच्छा अभ्यास क्या है?

हमेशा की तरह, अपने समय के लिए धन्यवाद।

+0

मैंने उन कार्यों को देखा है जो "पूरा होने के लिए भाग गए" जब वास्तव में उन्होंने एक समग्र अपवाद फेंक दिया। उस प्रकार की त्रुटि हैंडलिंग काम नहीं करती है। क्यों न केवल कोशिश/पकड़ का उपयोग करें? –

+0

क्या आप पृष्ठभूमि थ्रेड पर या वास्तविक निरंतरता प्रतिनिधि विधि में कहा जाने वाला तरीका है? – MoonKnight

उत्तर

12

आप AggregateException के लिए देख रहा है अपने प्रतिनिधियों के भीतर पारंपरिक ट्राई/कैच उपयोग कर सकते हैं तो आप विशिष्ट निरंतरता है कि केवल कभी चलेंगे, तो पूर्ववर्ती TaskContinuationOptions.OnlyOnFaulted विकल्प का उपयोग कर गलती की है पर श्रृंखला कर सकते हैं। बाद वाला दृष्टिकोण बहुत साफ कार्य वर्कफ़्लो को परिभाषित करने की अनुमति देता है। उदाहरण के लिए:

Task myRootTask = ....; 

myRootTask.ContinueWith(rootAntecdent => 
{ 
    // this will only be executed if the antecedent completed successfully, no need to check for faults 
}, 
TaskContinuationOptions.OnlyOnRanToCompletion); 

myRootTask.ContinueWith(rootAntecedent => 
{ 
    // this will only be executed if the antecedent faulted, observe exception and handle accordingly 
}, 
TaskContinuationOptions.OnlyOnFaulted); 
2

MSDN है एक काफी अच्छी तरह से लिखा "कैसे करने के लिए" विषय पर: here

आप वे केवल एक try/catch(AggregateException) ब्लॉक का उपयोग करें, तो अपवाद वे जानते हैं कि ae.Handle(lambda) में संभाल करने के लिए कैसे फ़िल्टर कर नोटिस और एप्लिकेशन बंद कर देगा अगर कुछ बाएं हैं जो हैंडलबल नहीं हैं।

+0

मुझे आपके लिंक प्रदान किए जाने वाले उदाहरणों के बारे में पता है और आपके पास धोखाधड़ी के साथ कोई समस्या नहीं है _this way_। मेरा मुद्दा यह है कि पूरे निरंतरता प्रतिनिधि को बिना किसी प्रयास के घेरे के निरंतरता से बाहर निकाले जाने वाले निष्पादन को कैसे संभालना है, फिर यह एकमात्र तरीका हो सकता है। मैं असली दुनिया कोड के लिए सबसे अच्छा पैराक्टिस जानना चाहता हूं, माइक्रोसॉफ्ट खिलौना कोड सर्वोत्तम अभ्यास नहीं। चीयर्स। लिंक के लिए – MoonKnight

+0

+1। बहुत उपयोगी – SleepyBoBos

+0

ओपी यह जानना चाहता है कि प्रतीक्षा किए बिना इसे कैसे किया जाए। सभी उदाहरण कार्य के लिए प्रतीक्षा करें। इसे आजमाएं [http://msdn.microsoft.com/en-us/library/dd997415.aspx] लिंक। –