2009-10-23 11 views
7

अपने आवेदन में मैं एक रूप है कि तुल्यकालन प्रक्रिया शुरू है और कारणों की संख्या के लिए मैं केवल एक तुल्यकालन एक समय में चलाने की अनुमति देना चाहते हैं। इसलिए मैं यह बताते हैं कि सिंक कार्य प्रगति पर है मेरी फार्म के लिए एक स्थिर bool क्षेत्र जोड़ा गया है और इतना है कि पहले धागा तुल्यकालन शुरू कर सकता है, लेकिन अगर यह पहले से ही सेट नहीं था सच करने के लिए इस क्षेत्र को स्थापित करने के लिए एक ताला जोड़ दिया है जब यह हर दूसरे धागा चल रहा है कि शुरू करने की कोशिश करेंगे इसे समाप्त कर दिया जाएगा।सी # ताला और कोड विश्लेषण चेतावनी CA2002

मेरे कोड कुछ इस तरह है:

internal partial class SynchronizationForm : Form 
{ 
    private static volatile bool workInProgress; 

    private void SynchronizationForm_Shown(object sender, EventArgs e) 
    { 
     lock (typeof(SynchronizationForm)) 
     { 
      if (!workInProgress) 
      { 
       workInProgress = true; 
      } 
      else 
      { 
       this.Close(); 
      } 
     } 
    } 
} 

यह अच्छी तरह से काम कर रहा है, लेकिन मैं निम्न चेतावनी संदेश प्राप्त हो रहा है, जब मैं अपने प्रोजेक्ट पर कोड विश्लेषण चलाएँ:

CA2002: माइक्रोसॉफ्ट। विश्वसनीयता: 'सिंक्रनाइज़ेशनफॉर्म। सिंक्रनाइज़ेशनफॉर्म_शॉउन (ऑब्जेक्ट, इवेंटआर्ग)' लॉक प्रकार 'टाइप' के संदर्भ पर ताले। मजबूत पहचान के साथ किसी ऑब्जेक्ट के विरुद्ध लॉक के साथ इसे बदलें।

क्या कोई मुझे बता सकता है कि मेरे कोड में क्या गलत है और मैं चेतावनी देने के लिए इसे कैसे सुधार सकता हूं। इसका क्या अर्थ है कि ऑब्जेक्ट की मजबूत पहचान है?

उत्तर

10

क्या गलत है कि आप कुछ सार्वजनिक (typeof(SynchronizationForm)) पर लॉक कर रहे हैं जो आपके कोड से हर जगह सुलभ है और यदि कुछ अन्य धागे इस चीज़ पर ताले लगाते हैं तो आपको डेडलॉक मिलता है।

private static object _syncRoot = new object(); 
... 
lock (_syncRoot) 
{ 

} 

यह आपको गारंटी देता है कि यह केवल SynchronizationForm कि ताला के अधिकारी कर सकते हैं: सामान्य तौर पर यह केवल निजी स्थिर वस्तुओं पर लॉक करने के लिए एक अच्छा विचार है।

+1

यह सच है, लेकिन "कमजोर पहचान" वाले ऑब्जेक्ट्स को लॉक करना अन्य कारणों से भी अव्यवस्थित है। –

6

MSDN explanation of the rule

एक वस्तु से एक कमजोर पहचान करने के लिए जब यह सीधे आवेदन डोमेन सीमाओं के पार पहुँचा जा सकता है कहा जाता है। एक थ्रेड जो किसी ऑब्जेक्ट पर लॉक प्राप्त करने का प्रयास करता है जिसमें कमजोर पहचान होती है उसे एक दूसरे ऑब्जेक्ट में एक दूसरे थ्रेड द्वारा अवरुद्ध किया जा सकता है जिसमें एक ही ऑब्जेक्ट पर लॉक होता है।

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

3

समस्या यह है कि typeof (SynchronizationForm) एक निजी ताला वस्तु, जिसका मतलब है कि कोड के किसी भी अन्य टुकड़े पर लॉक करने के लिए है, जो गतिरोध में परिणाम सकता है इसका इस्तेमाल कर सकते नहीं है।

var form = new SynchronizationForm(); 
lock(typeof(SynchronizationForm)) 
{ 
    form.SomeMethodThatCausesSynchronizationForm_ShownToBeCalled(); 
} 

फिर गतिरोध हो जाएगा: उदाहरण के लिए कुछ अन्य कोड ऐसा किया है। इसके बजाय आपको सिंक्रनाइज़ेशनफॉर्म क्लास में एक निजी लॉक ऑब्जेक्ट को डिलीयर करना चाहिए और इसके बजाय उस पर लॉक करना चाहिए।

2

System.Type कक्षा के ऑब्जेक्ट को कक्षा के स्थिर तरीकों के लिए पारस्परिक-बहिष्करण लॉक के रूप में आसानी से उपयोग किया जा सकता है।

स्रोत: http://msdn.microsoft.com/en-us/library/aa664735(VS.71).aspx

डौग जवाब देने के लिए जोड़ने के लिए, क्या तुम यहाँ एक लॉकिंग व्यवस्था है जिसके केवल, स्थिर तरीकों में इस्तेमाल किया जाना चाहिए एक उदाहरण विधि में इस्तेमाल किया जा रहा है।

+1

डॉग के उत्तर में लिंक द्वारा एमएसडीएन में दिए गए कारणों के लिए सिस्टम पर लॉकिंग अब अच्छा अभ्यास नहीं माना जाता है। आदर्श रूप से कथन और कोड उदाहरण सी # भाषा spec से हटा दिया जाएगा। –

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