2011-06-06 13 views
23

क्या कोई मुझे बता सकता है कि BlockReentrancy का उद्देश्य ObservableCollection<T> में क्या है?ObservableCollection में BlockReentrancy <T>

MSDN एक उदाहरण के रूप निम्नलिखित पता चलता है:

//The typical usage is to wrap an OnCollectionChanged call within a using scope, as in the following example: 

using (BlockReentrancy()) 
{ 
    // OnCollectionChanged call 
} 

लेकिन यह मेरे लिए स्पष्ट करने के लिए क्या उद्देश्य है प्रतीत नहीं होता। किसी को भी समझाने की परवाह है?

+0

इसे 'BlockReëntrancy' –

उत्तर

26

एक ObservableCollectionINotifyCollectionChanged लागू करता है और इसलिए इसमें CollectionChanged ईवेंट है। यदि इस घटना के लिए कोई ग्राहक है, तो वे संग्रह को संग्रह को संशोधित कर सकते हैं जबकि संग्रह पहले ही अधिसूचना की प्रक्रिया में है। चूंकि CollectionChanged ईवेंट वास्तव में क्या बदलता है इसका ट्रैक रखता है, यह बातचीत बहुत गन्दा हो सकती है।

परिणामस्वरूप, ObservableCollection एक विशेष मामले के रूप में, CollectionChanged ईवेंट के एक ग्राहक को अपने हैंडलर से संग्रह को संशोधित करने की अनुमति देता है। लेकिन CollectionChanged हैंडलर से संग्रह को संशोधित करते हुएCollectionChanged ईवेंट में संग्रह को संशोधित करने से को अस्वीकार करता है।

विधियों की जोड़ी BlockReentrancy और CheckReentancy इस तर्क को लागू करने के लिए उपयोग की जाती है। BlockReentrancyOnCollectionChanged विधि की शुरुआत में उपयोग किया जाता है और संग्रह को संशोधित करने वाले सभी तरीकों में CheckReentancy का उपयोग किया जाता है।

+0

क्या यह थ्रेड सुरक्षा का समर्थन करने के लिए प्रयोग किया जाता है? – deathrace

+0

बहुत दिलचस्प है कि एमएसडीएन दस्तावेज इस छोटे से तथ्य का जिक्र करने में असफल रहता है, कि चेकरेंटरेंसी केवल पुनर्वितरण को रोक देगा जब संग्रह चेंज किए गए ईवेंट से जुड़े एक से अधिक हैंडलर हैं। – treaschf

+1

"संग्रह संग्रहित हैंडलर से संग्रह को संशोधित करने में यह अस्वीकार करता है यदि संग्रहChanged ईवेंट में दो या दो से अधिक ग्राहक हैं।" क्या होगा यदि केवल एक ग्राहक है लेकिन संग्रह में संशोधन करने वाले दो कार्यकर्ता धागे हैं? उस स्थिति में, क्या मुझे ऑपरेशन लॉक करने के लिए एन्टर लॉक का उपयोग करना चाहिए जैसे कि सम्मिलित करें और निकालें और ऑनकॉलक्शन चेंज हैंडलर को लॉक करें? – Felix

11

यह एक और विधि के रूप में ClearItems, InsertItem, MoveItem, RemoveItem, SetItem संग्रह संशोधित करने से पहले जांच CheckReentrancy()CheckReentrancy()

protected void CheckReentrancy() 
{ 
    if ((this._monitor.Busy && (this.CollectionChanged != null)) && (this.CollectionChanged.GetInvocationList().Length > 1)) 
    { 
     throw new InvalidOperationException(SR.GetString("ObservableCollectionReentrancyNotAllowed")); 
    } 
} 

इस तरह के तरीके है BlockReentrancy()

protected IDisposable BlockReentrancy() 
{ 
    this._monitor.Enter(); 
    return this._monitor; 
} 

का कार्यान्वयन है।

तो नीचे दिया गया कोड गारंटी देता है कि संग्रह using के अंदर नहीं बदला जाएगा, लेकिन केवल तभी होगा जब एक से अधिक हैंडलर CollectionChanged ईवेंट की सदस्यता लें।

using BlockReentrancy()) 
{ 
    CollectionChanged(this, e); 
} 

यह उदाहरण के BlockReentrancy()

private static void Main() 
{ 
    collection.CollectionChanged += CollectionCollectionChanged1; 
    collection.CollectionChanged += CollectionCollectionChanged2; 
    collection.Add(1); 
} 

private static void CollectionCollectionChanged1(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    collection.Add(2); // this line will throw exception 
} 

private static void CollectionCollectionChanged2(object sender, NotifyCollectionChangedEventArgs e) 
{ 
} 
+1

उच्चारण करें आपका प्रदर्शन कोड 'StackOverflowException' को' अवैधऑपरेशन अपवाद 'नहीं फेंक देगा। इस मामले में पुनर्वितरण की जांच नहीं की जा रही है। मेरा जवाब देखें –

+0

@ रिक स्लैडकी - आप सही हैं। –

2

reentrancy प्रभाव को दर्शाता है है जब एक विधि कुछ करता है प्रत्यक्ष या परोक्ष रूप का कारण बनता है कि उस विधि फिर से लागू किया जा करने के लिए, संभवतः रिकर्सिवली। इस मामले में, यदि आप हैंडलर के भीतर से संग्रह को बदलने से रोकना चाहते हैं तो उपयोग ब्लॉक को ऑनकॉलेक्शन चेंज प्रतिनिधि के अंदर उपयोग किया जाना चाहिए; इसे बदलने का प्रयास अपवाद फेंक देगा। यदि आपने इसका उपयोग नहीं किया है, तो संग्रह को संशोधित करने के किसी भी प्रयास से ऑनकोलेक्शन को फिर से बुलाया जाएगा।

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