2009-12-31 5 views
8

में कंडीशन वेरिएबल & मॉनीटर सी # में उपयोग किए गए हैं?सी #

क्या कोई मुझे एक उदाहरण दे सकता है?

+2

साथ ही लॉक-बयान और मॉनिटर वर्ग के रूप में, WaitHandles पर एक नजर है (http://msdn.microsoft.com/en-us/library/system.threading.waithandle.aspx) जो कर सकते हैं बहुत उपयोगी हो और आपको उबाऊ बॉयलरप्लेट से बचाएं। – Skurmedel

उत्तर

12

है कि आप नेट में संकेतन के लिए बस का उपयोग एक शर्त चर के बराबर सार WaitHandle वर्ग है। इसके व्यावहारिक कार्यान्वयन मैनुअल रीसेट इवेंट और ऑटोरसेटवेन्ट कक्षाएं हैं।

एक शर्त चर जो आप मॉनीटर के रूप में उपयोग करते हैं सिस्टम की आवश्यकता होती है। थ्रेडिंग। मॉनिटर। सी # lock कथन का उपयोग करना बहुत आसान बनाता है, यह सुनिश्चित करता है कि मॉनिटर हमेशा बाहर निकलने() कॉल को प्रोग्राम किए बिना बाहर निकलता है।

+2

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

+0

बहुत अच्छा मुद्दा, मैंने इसे फिर से लिखा। धन्यवाद। –

+5

रुको (पन क्षमा करें)। क्या उनमें से कोई वास्तव में एक शर्त चर के बराबर बराबर है ?? मेरी गैर-विशेषज्ञ आंखों के लिए वे एक शर्त चर की तरह कुछ भी नहीं हैं। असल में मैंने एक वेबपृष्ठ देखा है जो दिखाता है कि ऑटो कर्सेट ऑब्जेक्ट्स जैसे विंडोज कर्नेल ऑब्जेक्ट्स से एक कंडीशन वैरिएबल कैसे बनाया जाए, और यह एक बहुत ही जटिल प्रक्रिया है जिसमें एक से अधिक कर्नेल ऑब्जेक्ट शामिल हैं ... – mackenir

3

आप लॉक ऑब्जेक्ट का उपयोग कर सकते हैं जो मॉनिटर क्लास के लिए सिंटैक्टिक चीनी के रूप में कार्य करता है।

lock(someObject) 
{ 
    // Thread safe code here. 
} 

http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.80%29.aspx

+3

एक छोटा सुधार, यह कोई ऑब्जेक्ट नहीं है, लेकिन एक कीवर्ड है, और लोअरकेस वर्तनी है, 'लॉक' :) – Skurmedel

+0

धन्यवाद, काम पर वीबी.नेट में विकास कर रहा है, इसलिए मस्तिष्क पर सिंकलॉक था और सिंक भाग हेह हटा दिया । –

2

मैनुअल रीसेट और दोस्तों के विकल्प के रूप में, विंडोज अब स्थिति चर के लिए native support प्रदान करता है। मैंने इसे स्वयं बेंचमार्क नहीं किया है, लेकिन देशी एपीआई का लाभ उठाने पर आपका प्रदर्शन बेहतर होगा।

यहाँ एक कोड परियोजना लेख कैसे इस (अपेक्षाकृत नया) तक पहुँचने के लिए सी # से निर्माण बताते हैं कि बताया गया है:

A .NET Wrapper for the Vista/Server 2008 Condition Variable

0

इस संस्करण atomically एक Mutex या ReaderWriterLockSlim जबकि संकेत के लिए इंतज़ार कर बातें बताता है, और लौटने से पहले यह पुन: लॉक - जो पॉज़िक्स तरीका है।

using System.Collections.Concurrent; 

namespace System.Threading.More { 
    public class ConditionVariable { 
     private readonly ConcurrentQueue<ManualResetEventSlim> _waitingThreads = new ConcurrentQueue<ManualResetEventSlim>(); 

     /// <summary> 
     ///  Atomically unlocks and waits for a signal. 
     ///  Then relocks the mutex before returning 
     /// </summary> 
     /// <param name="mutex"></param> 
     public void Wait(Mutex mutex) { 
      if (mutex == null) { 
       throw new ArgumentNullException("mutex"); 
      } 
      var waitHandle = new ManualResetEventSlim(); 
      try { 
       _waitingThreads.Enqueue(waitHandle); 
       mutex.ReleaseMutex(); 
       waitHandle.Wait(); 
      } finally { 
       waitHandle.Dispose(); 
      } 
      mutex.WaitOne(); 
     } 

     public void WaitRead(ReaderWriterLockSlim readerWriterLock) { 
      if (readerWriterLock == null) { 
       throw new ArgumentNullException("readerWriterLock"); 
      } 
      var waitHandle = new ManualResetEventSlim(); 
      try { 
       _waitingThreads.Enqueue(waitHandle); 
       readerWriterLock.ExitReadLock(); 
       waitHandle.Wait(); 
      } finally { 
       waitHandle.Dispose(); 
      } 
      readerWriterLock.EnterReadLock(); 
     } 

     public void Signal() { 
      ManualResetEventSlim waitHandle; 
      if (_waitingThreads.TryDequeue(out waitHandle)) { 
       waitHandle.Set(); 
      } 
     } 

     public void Broadcast() { 
      ManualResetEventSlim waitHandle; 
      while (_waitingThreads.TryDequeue(out waitHandle)) { 
       waitHandle.Set(); 
      } 
     } 
    } 
}