2012-06-11 8 views
6

मैं इस कोड को चला रहा हूं और यह उचित मात्रा में सीपीयू का उपयोग कर रहा है, भले ही यह ज्यादातर समय से बिल्कुल कुछ नहीं कर रहा है।किसी शर्त को पूरा होने तक ऑपरेशन को अवरुद्ध कैसे करें?

while (this.IsListening) 
{ 
    while (this.RecievedMessageBuffer.Count > 0) 
    { 
     lock (this.RecievedMessageBuffer) 
     { 
      this.RecievedMessageBuffer[0].Reconstruct(); 
      this.RecievedMessageBuffer[0].HandleMessage(messageHandler); 
      this.RecievedMessageBuffer.RemoveAt(0); 
     } 
    } 
} 

किसी शर्त को पूरा होने तक ब्लॉक करने का सबसे अच्छा तरीका क्या है?

+4

'थ्रेड। सो()'? –

+0

थ्रेड। नींद() यूआई को भी अवरुद्ध करता है। –

+4

@RanhiruCooray नहीं, यह लगभग हमेशा * गलत * उत्तर है। इस नौकरी के लिए समर्पित संरचनाएं हैं, जैसे मार्क द्वारा सुझाए गए वेटहैंडल। Http://stackoverflow.com/questions/9417260/when-is-it-sensible-to-use-thread-sleep –

उत्तर

7

मान लें कि आप .NET 4 का उपयोग कर रहे हैं, मैं RecievedMessageBuffer को BlockingCollection स्विच करने का सुझाव दूंगा। जब आप इसमें संदेश डाल रहे होते हैं, तो इसे Add विधि पर कॉल करें। जब आप एक संदेश पुनर्प्राप्त करना चाहते हैं, तो उसे Take या TryTake विधियों पर कॉल करें। एक संदेश उपलब्ध होने तक रीडिंग थ्रेड को अवरुद्ध कर देगा, आपके मूल उदाहरण की तरह सीपीयू जलाने के बिना।

// Somewhere else 
BlockingCollection<SomethingLikeAMessage> RecievedMessageBuffer = new BlockingCollection<SomethingLikeAMessage>(); 


// Something like this where your example was 
while (this.IsListening) 
{ 
    SomethingLikeAMessage message; 
    if (RecievedMessageBuffer.TryTake(out message, 5000); 
    { 
     message.Reconstruct(); 
     message.HandleMessage(messageHandler); 
    } 
} 
+1

बहुत बहुत धन्यवाद! जो मुझे चाहिए उसके लिए यह सही है! मैं पहले सिंक्रोनिज्ड कोलेक्शन <> का उपयोग कर रहा था लेकिन ब्लॉकिंग कोलेक्शन <> भी थ्रेड सुरक्षित है, यह मैं जो कर रहा हूं उसके लिए यह सही है! सबकुछ अब शानदार रूप से चिकना चल रहा है! – MJLaukala

9

WaitHandle का उपयोग करें।

WaitHandle waitHandle = new AutoResetEvent(); 

// In your thread. 
waitHandle.WaitOne(); 

// In another thread signal that the condition is met. 
waitHandle.Set(); 

आप भी अपने वर्ग के इंटरफेस को बदलने नए डेटा पढ़ने के लिए है जब वहाँ एक घटना को बढ़ाने के लिए विचार कर सकते हैं। फिर आप इवेंट हैंडलर के अंदर अपना कोड डाल सकते हैं।

+0

मुझे WaitHandles के साथ कुछ परीक्षण करना होगा। आज से पहले उनके बारे में कभी नहीं पता था। कुछ हफ्ते पहले मल्टीथ्रेडिंग के साथ कभी भी गंभीर नहीं था। – MJLaukala

+0

मैं 'सेट()' विधि के साथ 'WaitHandle' का उपयोग नहीं कर सका। मुझे लगता है कि इसके बजाय कम से कम 'EventWaitHandle' होना चाहिए। – Gucu112

2

कोड की रेखाओं के ऊपर और विशेष रूप से AutoResetEvent संस्करण 3.5 में उपलब्ध है। कुछ मामूली सुधार के साथ उपरोक्त सरल कोड बहुत प्रभावी है क्योंकि यह नींव एपीआई के काम करता है और बंद करता है। सुधार

AutoResetEvent waitHandle = new AutoResetEvent (false) होना चाहिए; तर्क झूठी के साथ निर्माता निर्माता प्रतीक्षा करें() प्रतीक्षा करने के लिए क्योंकि AutoResetEven रीसेट नहीं किया गया है (झूठा)। इंटरफ़ेस WaitHandle का उपयोग करने का बहुत अधिक लाभ नहीं है, इसलिए मैं केवल ऑटोरसेट इवेंट का उपयोग करता हूं क्योंकि यह विधि सेट करता है और प्रतीक्षा करें इस मामले में प्रतीक्षा करें। सबसे महत्वपूर्ण बात यह है कि कन्स्ट्रक्टर तर्क और झूठा होना चाहिए।

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

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