2012-01-25 8 views
11

मैं निम्नलिखित डिजाइन पैटर्न:यह जांचने के लिए कि मैन्युअल रीसेट इवेंट का निपटारा कब किया गया है, इसे इवेंट हैंडलर के अंदर सेट करने की कोशिश करते समय?

var myObjectWithEvents = new ObjectWithEvents(); 
    using (var mre = new ManualResetEvent(false)) { 
     var onEvent = new EventHandler<EventArgs>((sender, e) => { mre.Set(); }); 
     try { 
      myObjectWithEvents.OnEvent += onEvent; 
      var task = Task.Factory.StartNew(() => { 
       myObjectWithEvents.DoSomethingThatShouldRaiseAnEvent(); 
      }); 
      var timedOut = !mre.WaitOne(10000); 
     } 
     finally { 
      myObjectWithEvents.OnEvent -= onEvent; 
     } 
    } 

मेरे मुद्दा यह है कि अगर OnEventWaitOne बार बाहर और ब्लॉक का उपयोग से बाहर निष्पादन चरणों के बाद उठाया है, स्थानीय onEvent ईवेंट हैंडलर अभी भी कहा जाता है और करने की कोशिश हो जाएगा ManualResetEvent mre सेट करें जो पहले ही डिस्पोजेड हो चुका है, भले ही onEvent को OnEvent से अनियंत्रित किया जाना चाहिए था।

एक साधारण वैकल्पिक हल यदि mre पहले से ही निपटारा कर दिया गया है की जाँच करने के होगा, लेकिन दुर्भाग्य से इस तरह का कोई क्षेत्र है, और मेरा मानना ​​है कि एक कोशिश कैच ब्लॉक के अंदर mre.Set() लपेटकर अपवाद की अनदेखी करने कि अपवाद काफी हो सकता है नहीं दिया साफ है बार बार।

उपर्युक्त कोड पैटर्न (यानी किसी घटना को उठाने का इंतजार) इस उद्देश्य के बिना चलने के उद्देश्य को प्राप्त करने के लिए सबसे अच्छा और सरल तरीका क्या है?

संपादित करें: अपने जवाब के लिए धन्यवाद, मैं निम्नलिखित एक्सटेंशन बनाया और mre.TrySet() साथ mre.Set() लाए गए:

public static void TrySet(this ManualResetEvent mre) { 
     if (!mre.SafeWaitHandle.IsClosed) mre.Set(); 
    } 
+0

क्या आप अपनी आवेदन आवश्यकताओं के बारे में अधिक जानकारी दे सकते हैं? आप "उपर्युक्त कोड पैटर्न के उद्देश्य को प्राप्त करने का सबसे अच्छा और सरल तरीका" मांगते हैं, लेकिन इससे हमें अनुमान लगाया जाता है कि आपकी आवश्यकताओं को आपके वर्तमान कोड से क्या बंद कर दिया गया है। – Justin

+0

क्या यह डिस्पोजेड एमआरई पर सेट() को निष्पादित करने में कोई समस्या उत्पन्न करता है? – sll

+0

डिस्प्ले मैर पर हाँ mre.Set() एक अपवाद फेंक देगा ... –

उत्तर

7

आप mre.SafeWaitHandle.IsClosed संपत्ति

9
ManualResetEvent.SafeWaitHandle.IsClosed 

अजीब लगता है, लेकिन केवल बात यह है कि निपटाने करता safeHandler बंद करने के लिए है , जो एकमात्र वस्तु है जिसका उद्देश्य निपटान करना है ...

सेफवाइटहैंडल का निपटान, इस संपत्ति को गलत से सही में बदलता है।

+0

+1 क्योंकि आप पहले हैं जिन्होंने 'IsClosed' ध्वज – sll

+0

धन्यवाद एसएसएल का सुझाव दिया है! की सराहना की –

1

एक मामले के रूप में से यह जांच करने के लिए सरल बूलियन स्विच जो यह बताते हैं कि ManualResetEvent सेटिंग वास्तविक है का उपयोग कर की कोशिश की कोशिश कर सकते हैं:

bool isMreSync = true; 
var myObjectWithEvents = new ObjectWithEvents(); 
using (var mre = new ManualResetEvent(false)) 
{ 
    var onEvent = new EventHandler<EventArgs>((sender, e) => 
       { 
        if (isMreSync) 
        { 
         mre.Set(); 
        } 
       }); 

    // try ... finally block 
} 

isMreSync = false; 

तो घटना हो सकती है असीमित रूप से निष्पादित - बूलियन स्विच तक पहुंच सिंक्रनाइज़ करें।

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