8

तक पहुंचने से रोकने में मुश्किल हो रही है। मैं Web Hook पर .NET 4.0 में काम कर रहा हूं जो लैम्बडा को असीमित रूप से चलाएगा और फिर परिणाम पोस्ट करेगा एक पूरा यूआरआई जब यह खत्म हो जाता है।मैं टास्क को फेंकने वाले किसी भी अपवाद को संभालने के लिए चाहता हूं, लेकिन मुझे माता-पिता

मुझे यह काम करने के लिए मिला है, लेकिन अब मैं कार्य को फेंकने वाले किसी भी अपवाद को संभालने के लिए चाहता हूं, और मुझे माता-पिता तक पहुंचने से रोकने में मुश्किल हो रही है।

यहाँ मेरी कोड का हिस्सा है:

private readonly Func<T> _startTask; 
private readonly string _responseUri; 

public Task<T> Begin() 
{ 
    var task = new Task<T>(_startTask); 
    task.ContinueWith<T>(End); 
    task.Start(); 
    return task; 
} 

private T End(Task<T> task) 
{ 
    if (task.IsFaulted) 
    { 
     return HandleException(task); 
    } 

    var result = task.Result; 
    WebHookResponse.Respond(result, _responseUri); 
    return result; 
} 

private T HandleException(Task<T> task) 
{ 
    WebHookResponse.HandleException(task.Exception.InnerException, _responseUri); 
    return null; 
} 

एक वैकल्पिक संस्करण है कि मैं कॉल ContinueWith() की कोशिश की है दो बार एक निरंतरता रजिस्टर करने के लिए OnlyOnRanToCompletion चलाने के लिए और एक OnlyOnFaulted चलाने के लिए। (मुझे यकीन है कि अगर दो बार बुला ContinueWith() सही है नहीं कर रहा हूँ।):

public Task<T> Begin() 
{ 
    var task = new Task<T>(_startTask); 
    task.ContinueWith<T>(End, TaskContinuationOptions.OnlyOnRanToCompletion); 
    task.ContinueWith<T>(HandleException, TaskContinuationOptions.OnlyOnFaulted); 
    task.Start(); 
    return task; 
} 

private T End(Task<T> task) 
{ 
    var result = task.Result; 
    WebHookResponse.Respond(result, _responseUri); 
    return result; 
} 

private T HandleException(Task<T> task) 
{ 
    WebHookResponse.HandleException(task.Exception.InnerException, _responseUri); 
    return null; 
} 

तो बुनियादी तौर पर मैं प्रत्येक कार्य एक निरंतरता समारोह के माध्यम से अपने अपवाद को संभालने के लिए एक तरह से करना चाहते हैं। जैसा कि यह है कि हैंडलएक्सप्शन निरंतरता समारोह को उपर्युक्त उदाहरणों में से किसी एक में कभी नहीं कहा जा रहा है।

मैं एक परीक्षण मामले में अपवाद पैदा कर रहा हूं, और मुझे यह उल्लेख करना चाहिए कि मैं Tasks.WaitAll(tasks); कार्य का एक सरणी पर कॉल कर रहा हूं ताकि यह सुनिश्चित किया जा सके कि मेरे कार्य करने से पहले सभी कार्य पूर्ण हो गए हैं, और मुझे यकीन नहीं है कि उस कॉल में अंतर होता है कि कार्य द्वारा अपवादों को कैसे नियंत्रित किया जाता है। वर्तमान में WaitAll एक एग्रीगेशन अपवाद फेंकता है जो प्रत्येक कार्य के लिए अपवादों को जोड़ता है क्योंकि उन्हें हैंडलएक्सप्शन निरंतरता फ़ंक्शन द्वारा नियंत्रित नहीं किया जा रहा है।

+0

मुझे समस्या नहीं दिखाई दे रही है। आप क्या व्यवहार देख रहे हैं? –

+0

क्षमा करें, हैंडलएक्सप्शन निरंतरता समारोह नहीं कहा जा रहा है। एक समेकन अपवाद कार्य द्वारा फेंक दिया गया है। प्रतीक्षा करें (कार्य); कहते हैं। मैं एकत्रीकरण अपवाद नहीं देखना चाहता हूं। मैंने अभी सवाल को अद्यतन किया है। –

+0

@ मार्टिन ओवेन हाय, मेरे हैंडलएक्सप्शन कॉन्टीन्यूशन को भी नहीं कहा जा रहा है और मेरा UnobservedTaskException ईवेंट यहां भी नहीं निकाला जा रहा है: http://stackoverflow.com/questions/11831844/unobservedtaskexception-being-throw-but-it-is-handled-by- एक-कार्यवाहक-unobser क्या आपको कुछ समाधान मिला? – newway

उत्तर

1

शायद, हेनक होल्टरमैन के जवाब में, आदेश एक फर्क पड़ता है। यही है,

var task = new Task<T>(_startTask); 
task = task.ContinueWith<T>(HandleException, TaskContinuationOptions.OnlyOnFaulted); 
task = task.ContinueWith<T>(End, TaskContinuationOptions.OnlyOnRanToCompletion); 
task.Start(); 

यह सुनिश्चित करेगा कि हैंडलएक्सप्शन आवश्यक होने पर चलाएगा।

+0

नहीं, यह नहीं है। अगर आवश्यक हो तो दोनों निरंतरताओं को बुलाया जाएगा, भले ही आपने 'जारीविथ' कहा था (जाहिर है कि प्रत्येक बार 'टास्क कंटिन्यूशनऑप्शन' पारस्परिक रूप से अनन्य होते हैं)। –

+0

यदि आपने इसे उस क्रम में किया है, तो अंत में एकत्रित अपवादों को संभाला नहीं जाएगा। हैंडल अपवाद हमेशा आखिरी व्यक्ति होना चाहिए, जैसे सॉकर में एक स्वीपर सभी रक्षा के पीछे है, इसलिए यह कुछ भी हो सकता है जो एक ही चीज से हो सकता है। – Despertar

3

कार्य की अपवाद को देखते हुए एक कार्य निरंतरता अपवाद को संभाल नहीं पाती है। यह तब भी होता है जब आप काम खत्म होने पर प्रतीक्षा करते हैं।

आपने कहा था कि आप जोर से पहले WaitAll (कार्यों) को कॉल कर रहे थे। मैं शर्त लगा रहा हूं कि यदि आपने पर्याप्त समय दिया है तो आपकी निरंतरता चलती होगी, लेकिन प्रतीक्षा निरंतरता() पर अपवाद आमतौर पर आपके निरंतरता के चलने से पहले होता है। तो आपके निरंतरता को अपना काम पूरा करने का मौका देने से पहले आपके आवेषण शायद असफल हो गए थे।

1

मैं इस दृष्टिकोण का उपयोग करता हूं क्योंकि यह एक अच्छी घोषणात्मक धाराप्रवाह कोडिंग शैली प्रदान करता है और अपवाद हैंडलिंग पहलुओं के साथ आपका कोड कूड़ा नहीं करता है।

class Program 
{ 
    static void Main() 
    { 
     Task.Factory.StartNew(
      () => 
       { 
        throw new Exception(); 
       }) 
      .Success(() => Console.WriteLine("Works")) 
      .Fail((ex) => Console.WriteLine("Fails")).Wait(); 

     Console.ReadKey(); 
    } 
} 

public static class TaskExtensions 
{ 
    public static Task Success(this Task task, Action onSuccess) 
    { 
     task.ContinueWith((t) => 
     { 
      if (!t.IsFaulted) 
      { 
       onSuccess(); 
      } 
     }); 

     return task; 
    } 

    public static Task Fail(this Task task, Action<Exception> onFail) 
    { 
     return task.ContinueWith(
      (t) => 
      { 
       if (t.IsFaulted) 
       { 
        t.Exception.Handle(x => true); 
        onFail(t.Exception.Flatten()); 
       } 
      }); 
    } 
} 
संबंधित मुद्दे