2011-07-19 6 views
15

मैं वेब पर AggregateException का एक उदाहरण देखा है और मैं यह पता लगाने की कि यह कैसे तो मैं लिखा है सरल उदाहरण काम करता है लेकिन किसी कारण से मेरी कोडAggregateException सी # उदाहरण

कोई समझा सकते हैं काम नहीं करता है कोशिश कर रहा हूँ मुझे कई कार्यकर्ता धागे पर विभाजित हो जाता है समस्या

public static void Main() 
    { 
     try 
     { 
      Parallel.For(0, 500000, i => 
      { 
       if (i == 10523) 
        throw new TimeoutException("i = 10523"); 

       Console.WriteLine(i + "\n"); 
      }); 
     } 
     catch (AggregateException exception) 
     { 
      foreach (Exception ex in exception.InnerExceptions) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
     } 
    } 
+0

क्या काम नहीं कर रहा? आप क्या होने की उम्मीद कर रहे हैं? – Klinger

+0

टाइमआउट अपवाद को उपयोगकर्ता कोड – Dan

+0

द्वारा नियंत्रित नहीं किया गया था आप कह रहे हैं कि आप कैच ब्लॉक द्वारा अपवाद को संभालने की अपेक्षा कर रहे थे, लेकिन इसके बजाय आपको "टाइमआउट अपवाद उपयोगकर्ता कोड द्वारा प्रबंधित नहीं किया गया" है, है ना? यदि ऐसा है, तो याहिया उत्तर और टिप्पणियां शायद आप जो खोज रहे हैं। – Klinger

उत्तर

7

क्या जब समानांतर "नौकरी" का उपयोग कर (यहाँ 0 से 500000 करने के लिए बढ़ रहा है)। इनमें से प्रत्येक अपवाद फेंक सकता है। नमूना में अपवाद को 10523 पर काम कर रहे थ्रेड में होने के लिए कोड किया गया है। वास्तविक दुनिया परिदृश्य में एक से अधिक अपवाद हो सकते हैं (विभिन्न धागे में) - समेकित अपवाद केवल सभी "अपरिपक्व" है, जबकि समांतर चल रहा है ताकि आप किसी भी अपवाद नहीं खोना ...

+1

हाँ, यह ठीक है लेकिन मुझे समझ में नहीं आता है कि मुझे "त्रुटि" क्यों कह रही है कि उपयोगकर्ता कोड द्वारा टाइमआउट अपवाद को संभाला नहीं गया था। अपवाद को अपवाद नहीं करना चाहिए अपवाद को पकड़ना और इसे अपने काम को पूरा करने के लिए एक बार समानांतर कंसोल पर प्रिंट करना चाहिए? – Dan

+2

आप सही हैं लेकिन मुझे लगता है कि आपके द्वारा वर्णित व्यवहार केवल डीएस में चलने पर डीबगिंग के साथ हो रहा है। – Yahia

+0

@ डैन: वीएस के बाहर और उदाहरण के बिना अपना उदाहरण चलाकर मुझे अपवाद मिल गया है एक्सेगेट अपवाद: एक या अधिक त्रुटियां हुईं। – Klinger

3

AggregateException अक्सर अपवादों को पकड़ने के लिए उपयोग किया जाता है, जो Task को पूरा करने के लिए प्रतीक्षा करते समय हो सकता है। क्योंकि Task सामान्य रूप से कई अन्य लोगों में शामिल हो सकता है, हम नहीं जानते कि क्या एक या अधिक अपवाद फेंक दिए जाएंगे।

चेक निम्न उदाहरण:

// set up your task 
Action<int> job = (int i) => 
{ 
    if (i % 100 == 0) 
     throw new TimeoutException("i = " + i); 
}; 

// we want many tasks to run in paralell 
var tasks = new Task[1000]; 
for (var i = 0; i < 1000; i++) 
{ 
    // assign to other variable, 
    // or it will use the same number for every task 
    var j = i; 
    // run your task 
    var task = Task.Run(() => job(j)); 
    // save it 
    tasks[i] = task; 
} 

try 
{ 
    // wait for all the tasks to finish in a blocking manner 
    Task.WaitAll(tasks); 

} 
catch (AggregateException e) 
{ 
    // catch whatever was thrown 
    foreach (Exception ex in e.InnerExceptions) 
     Console.WriteLine(ex.Message); 
} 
0

यहाँ AggregateException का एक व्यावहारिक उपयोग एक अपवाद वस्तु से भीतरी अपवाद प्राप्त करने के लिए है,

private static Exception GetFirstRealException(Exception exception) 
    { 
     Exception realException = exception; 
     var aggregateException = realException as AggregateException; 

     if (aggregateException != null) 
     { 
      realException = aggregateException.Flatten().InnerException; // take first real exception 

      while (realException != null && realException.InnerException != null) 
      { 
       realException = realException.InnerException; 
      } 
     } 

     return realException ?? exception; 
    } 
5

पांच साल पुरानी है और कोई भी सही जवाब दिया ? आपको आंतरिक अपवादों पर "हैंडल" कॉल करने की आवश्यकता है। "हैंडल" पर एमएसडीएन के दस्तावेज से:

भविष्यवाणी का प्रत्येक आमंत्रण यह संकेत करने के लिए सही या गलत लौटाता है कि अपवाद संभाला गया था या नहीं। सभी आमंत्रणों के बाद, यदि कोई अपवाद अनचाहे हो गया, तो सभी अनचाहे अपवादों को एक नए समेकित अपवाद में रखा जाएगा जिसे फेंक दिया जाएगा। अन्यथा, हैंडल विधि बस वापस आती है। यदि भविष्यवाणी के किसी भी आमंत्रण में अपवाद फेंकता है, तो यह किसी और अपवाद की प्रसंस्करण को रोक देगा और तत्काल अपवाद को प्रचारित करेगा।

उदाहरण कोड, भी MSDN से:

public static void Main() 
    { 
     var task1 = Task.Run(() => { throw new CustomException("This exception is expected!"); }); 

     try { 
      task1.Wait(); 
     } 
     catch (AggregateException ae) 
     { 
     // Call the Handle method to handle the custom exception, 
     // otherwise rethrow the exception. 
     ae.Handle(ex => { if (ex is CustomException) 
          Console.WriteLine(ex.Message); 
          return ex is CustomException; 
         }); 
     } 
    } 
संबंधित मुद्दे