2009-08-30 17 views
6

मैं अपने अतुल्यकालिक प्रोग्रामिंग (BeginInvoke/EndInvoke) में एक अपवाद संचालन दृष्टिकोण करना चाहते हैं जिसमें अगर धागा (BeginInvoke) में से किसी एक में विफल रहता है, तो मैं अन्य सभी asynchrounous प्रसंस्करण धागा काम करना बंद करना चाहते हैं। कृपया ?, कुछ समाधान का सुझाव नीचे मैं अपने नमूना कोड भी संलग्न कर रहा हूँ:असीमित मल्टीथ्रेडिंग अपवाद हैंडलिंग?

public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto> requestDto) 
{ 
    List<ThreadResultDto> resultDto = new List<ThreadResultDto>(); 
    List<IAsyncResult> asyncResults = new List<IAsyncResult>(); 

    foreach (ThreadRequestDto t in requestDto) 
    { 
     //Create a delegate. 
     DoSomeAsynchWorkDelegate del = new DoSomeAsynchWorkDelegate(DoSomeAsynchWork); 
     // Initiate the asynchronous call 
     IAsyncResult a = del.BeginInvoke(t,null, del); 
     //IAsyncResult a = del.BeginInvoke(t, null,null); 
     asyncResults.Add(a); 
    } 

    foreach (IAsyncResult ar in asyncResults) 
    { 
     // wait for each one to complete, then call EndInvoke, passing in the IAsyncResult. 
     // We cast ar.AsyncState to a DoSomeAsynchWorkDelegate, as we passed it in as the second parameter to BeginInvoke. 
     ar.AsyncWaitHandle.WaitOne(); 

     //AsyncState property of IAsyncResult is used to get the delegate that was used to call that method 
     DoSomeAsynchWorkDelegate del = (DoSomeAsynchWorkDelegate)ar.AsyncState; 

     // Call EndInvoke to get the result. Add the result to the list of items. 
     resultDto.Add(del.EndInvoke(ar)); 
    } 

    return resultDto; 
} 
+1

FYI करें, अतुल्यकालिक की आम तौर पर स्वीकार संक्षिप्त नाम Async है, नहीं Asynch :) –

उत्तर

2

सबसे अच्छा तरीका शायद एक साझा ManualResetEvent उपयोग करने के लिए है।

उदाहरण के लिए:

class MyClass 
{ 
    private ManualResetEvent workFailedEvent = new ManualResetEvent(false); 

    public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto> requestDto) 
    { 
     workFailedEvent.Reset(); 

     // --- The rest of your code as written in your post --- 
    } 

    private void DoAsyncWorkFirst() 
    { 
     try 
     { 
      for (int i = 0; i < 10000; i++) 
      { 
       if (workFailedEvent.WaitOne(0, true)) 
       { 
        break; 
       } 

       // -- Do some work here --- 
      } 
     } 
     catch (MyException) 
     { 
      workFailedEvent.Set(); 
     } 
    } 

    private void DoAsyncWorkSecond() 
    { 
     try 
     { 
      for (int j = 0; j < 20000; j++) 
      { 
       if (workFailedEvent.WaitOne(0, true)) 
       { 
        break; 
       } 
       // --- Do some different work here --- 
      } 
     } 
     catch (MyOtherException) 
     { 
      workFailedEvent.Set(); 
     } 
    } 
} 

यहाँ दिलचस्प हिस्सा WaitOne (0, सच) करने के लिए कॉल है। यदि आप 0 के टाइमआउट का उपयोग करते हैं तो थ्रेड ब्लॉक नहीं होगा। चूंकि ManualResetEvent ओएस द्वारा सिंक्रनाइज़ है, इस विशेष विधि कॉल दौड़ की स्थिति के बारे में चिंता या अपना स्वयं का ताला लागू करने के लिए बिना एक संकेत के लिए जाँच करने के लिए एक सुविधाजनक तरीका है।

+1

एक अस्थिर bool भी एक समाप्ति ध्वज के रूप में काम नहीं करेंगे? – Amnon

+0

सिद्धांत में हां। कुछ मामलों में, यह भी तेज हो सकता है। लेकिन * अस्थिर * कीवर्ड साइड इफेक्ट का एक बहुत है - यह वास्तव में बदल जाता है जिस तरह से कोड हर ब्लॉक कि चर, न सिर्फ चर ही पहुँचता के लिए उत्पन्न होता है। मैं आम तौर पर * अस्थिर * फ़ील्ड तक ताले और सिंच्रो प्राइमेटिव पसंद करता हूं जब तक कि प्रदर्शन एक प्रमुख मुद्दा न हो। – Aaronaught

संबंधित मुद्दे