2010-04-22 14 views
8

यह एक ही वस्तु के लिए एक नेस्टेड ताले उपयोग करने के लिए एक प्रदर्शन को लागत है।नेस्टेड ताला

कहो हमने:

public void AddRange(IEnumeratable<Item> items) 
    { 
     lock (_syncObject) 
     { 
      foreach (Item item in items) 
      { 
       InsertItem(item); 
      } 
     } 
    } 

    public void InsertItem(Item item) 
    { 
     lock (_syncObject) 
     { 
      //.. 
     } 
    } 

यह ठीक है तो "प्रदर्शन की ओर" करना है?

अग्रिम धन्यवाद।

उत्तर

6

लॉक लागत है, मैं सुझाव है कि आप इस तरह अपने कोड लागू करने के लिए:

public void AddRange(IEnumeratable<Item> items) 
{ 
    lock (_syncObject) // Locking only once. 
    { 
     foreach (Item item in items) 
     { 
      InsertItemImpl(item); 
     } 
    } 
} 

private void InsertItemImpl(Item item) 
{ 
    // inserting the item 
} 

public void InsertItem(Item item) 
{ 
    lock (_syncObject) 
    { 
     InsertItemImpl(item); 
    } 
} 
2

lock मुक्त नहीं है। यह में है जो लौटने से पहले कुछ चीजों की जांच के लिए है। कितनी चीजें और क्या करना है, कार्यान्वयन पर निर्भर करता है। मैं लगता होगा कि उपयोग इस तरह की आम है और एमएस इस USECASE के लिए कुछ अनुकूलन किया था।

मैं अभी भी सलाह देते हैं कि आप सभी एक शॉट में आपका काम पूरा साथ AddRange का एक अलग कार्यान्वयन होगा। यह निश्चित रूप से कक्षा के बाकी इंटरफ़ेस पर निर्भर करता है (वहां श्रोताओं हैं और क्या वे संदेश प्राप्त कर सकते हैं कि कई ऑब्जेक्ट्स जोड़े गए थे)।

यह काफी आसान testcase है, एक अन्य लॉक के साथ नेस्टेड लॉकिंग के कुछ लाखों लोगों (आप क्या प्रस्ताव है) और एक ही है।

सूचना भी विभिन्न संभव आदेश अगर आप गैर नेस्टेड लॉक का उपयोग, आप एक सीमा को जोड़ रहे हैं के बीच में एक वस्तु प्राप्त हो सकता है:

AddRange _sync1 
    AddItem _sync2 
    AddItem _sync2 
    --- interruption, other thread calls: 
    AddItem _sync2 
    --- AddRange again: 
    AddItem _sync2 

जब एक भी _syncObject के साथ समन्वयन करना, कोई भी बाधित कर सकते हैं क्योंकि ताला पहले से ही किसी अन्य थ्रेड द्वारा आयोजित किया जाता है।

1

मैं नहीं जानता कि कैसे प्रदर्शन प्रभावित होता है, लेकिन जब हम यह प्रदर्शन में कमी की उम्मीद मैं सुझाव देंगे आप अपने कोड दूसरी तरह के आसपास लागू:

public void InsertItem(Item item) 
{ 
    AddRange(new IEnumeratable({item})) 
} 

public void AddRange(IEnumeratable<Item> items) 
{ 
    lock (_syncObject) 
    { 
     foreach (Item item in items) 
     { 
      // Insert code .. 
     } 
    } 
} 

@AddRange (नई IEnumeratable ({ आइटम}): मैं एक वाक्यविन्यास wizkid नहीं हूँ तो कृपया सही है अगर यह सही नहीं है!

+3

मुझे लगता है कि यह एक और तरीका नहीं बल्कि उसके बाद प्रत्येक जोड़ने आइटम के लिए नया संग्रह बनाने के लिए कार्यान्वयन सम्मिलित बाहर ले जाने के लिए बेहतर है। –

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