2008-08-12 13 views
52

मुझे किसी ऑब्जेक्ट को लॉक करने का प्रयास करने की आवश्यकता है, और यदि यह पहले से ही लॉक हो गया है (समय के बाद, या इसके बिना)।क्या सी # में ऑपरेशन "लॉक करने का प्रयास करें, समय समाप्त हो गया है"?

सी # लॉक स्टेटमेंट अवरुद्ध है।

उत्तर

34

मुझे विश्वास है कि आप Monitor.TryEnter() का उपयोग कर सकते हैं।

लॉक स्टेटमेंट केवल Monitor.Enter() कॉल और try catch ब्लॉक में अनुवाद करता है।

+0

क्या होगा यदि मैं अंतर-प्रक्रिया संगामिति के साथ काम कर रहा हूँ देखते हैं? क्या एक मटेक्स का उपयोग इसी तरह से करने का कोई तरीका है? –

80

एड के लिए आपके लिए सही कार्य है। बस Monitor.Exit() पर कॉल करना न भूलें। उचित सफाई की गारंटी के लिए आपको try-finally ब्लॉक का उपयोग करना चाहिए।

if (Monitor.TryEnter(someObject)) 
{ 
    try 
    { 
     // use object 
    } 
    finally 
    { 
     Monitor.Exit(someObject); 
    } 
} 
+0

+1, धन्यवाद! यदि आप चाहें तो थोड़ा बदलाव प्रस्तावित करें, केवल यादृच्छिक रूप से ब्रेसिज़ को बिना छेड़छाड़ किए बिना उन्नत संरचनाओं/पैटर्न का उपयोग करना हमेशा याद रखें। – ceztko

+0

@ceztko, क्या आप स्पष्टीकरण दे सकते हैं? आम तौर पर, एन संसाधनों को जारी करना, उदाहरण के लिए, सी # को एन नेस्टेड प्रयास-अंत में ब्लॉक की आवश्यकता होती है। उपयोग कथन केवल आईडीस्पोजेबल्स के लिए इससे बचने में मदद करता है। कोशिश-अंत में ब्लॉक को छोड़कर अपवाद की स्थिति में संसाधनों को लीक किया जा सकता है। उदाहरण के लिए, [मॉनीटर] (http://msdn.microsoft.com/en-us/library/aa720302 (v = VS.71) .aspx) दस्तावेज़ीकरण स्पष्ट करता है कि आखिरकार ब्लॉक आवश्यक है। आश्चर्यजनक रूप से, एड का लिंक इस पर उपेक्षा करता है। –

3

आप शायद इस खुद के लिए बाहर मिल जाएगा अब है कि दूसरों को सही दिशा में इशारा किया है, लेकिन TryEnter भी समय समाप्त पैरामीटर ले सकते हैं।

जेफ रिचटर की "सीएलआर वाया सी #" सीएलआर सराय के विवरण पर एक उत्कृष्ट पुस्तक है यदि आप अधिक जटिल चीजें प्राप्त कर रहे हैं।

public class TryLock : IDisposable 
{ 
    private object locked; 

    public bool HasLock { get; private set; } 

    public TryLock(object obj) 
    { 
     if (Monitor.TryEnter(obj)) 
     { 
      HasLock = true; 
      locked = obj; 
     } 
    } 

    public void Dispose() 
    { 
     if (HasLock) 
     { 
      Monitor.Exit(locked); 
      locked = null; 
      HasLock = false; 
     } 
    } 
} 

और फिर लॉक करने के लिए निम्न सिंटैक्स का उपयोग:

10

मैं एक ही समस्या थी, मैं एक वर्ग TryLock कि IDisposable लागू करता है और फिर ताला के दायरे को नियंत्रित करने के using कथन का उपयोग करती बना दी:

var obj = new object(); 

using (var tryLock = new TryLock(obj)) 
{ 
    if (tryLock.HasLock) 
    { 
     Console.WriteLine("Lock acquired.."); 
    } 
} 
संबंधित मुद्दे