2009-06-23 14 views
5

कतार की निगरानी करने का सबसे प्रभावी तरीका क्या है।कतार की निगरानी करने के लिए सबसे प्रभावी तरीका

कोड की Follwoing टुकड़ा संसाधनों का सबसे बड़ा हॉग है:

/// <summary> 
/// Starts the service. 
/// </summary> 
private void StartService() 
{ 
    while (true) 
    { 
     //the check on count is not thread safe 
     while (_MessageQueue.Count > 0) 
     { 
      Common.IMessage message; 
      // the call to GetMessageFromQueue is thread safe 
      if (_MessageQueue.GetMessageFromQueue(out message) == true) 
      { 
       if (message.RoutingInfo == Devices.Common.MessageRoutingInfo.ToDevice) 
       { 
        _Port.SerialPort.WriteLine(message.Message); 
       } 
       if (message.RoutingInfo == Devices.Common.MessageRoutingInfo.FromDevice) 
       { 
        OnDeviceMessageReceived(new Common.DeviceMessageArgs(message.Message)); 
       } 
      } 
     } 
    } 
} 

प्रारंभ सेवा पृष्ठभूमि धागा पर चलता है, _MessageQueue.Count करने के लिए कॉल सुरक्षित थ्रेड नहीं है, मैं MessageQueue में गिनती पर ताला लगा नहीं कर रहा हूँ। हालांकि मैं _MessageQueue.GetMessageFromQueue के कार्यान्वयन पर लॉक करता हूं। क्या मैं इस कुशल के बारे में गया हूं? क्या मुझे एक घटना को उठाना चाहिए हर बार कतार 0 की गणना से शून्य से अधिक हो जाती है?

उत्तर

5

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

+1

नहीं सोता है जब तक आप निर्माता के ऊपर कोई नियंत्रण है। उचित प्रतीक्षा/अधिसूचनाएं करने के लिए घटनाओं या संकेतों का उपयोग करें। –

+0

मैट क्यों? मेरे पास निर्माता पर नियंत्रण है। क्या मुझे कतार में कोई आइटम जोड़ा जाने पर एक घटना को उठाया जाना चाहिए? मैं waithandle में देखेंगे। – AndyMM

+0

+1। एक उदाहरण के लिए मेरा जवाब देखें। – dtb

1

यदि मुझे कुछ भी याद नहीं आया है - तो आप _messageQueue.Count संपत्ति पर व्यस्त प्रतीक्षा कर रहे हैं। मैं की तरह पर किया जाता है कुछ कर रही कोशिश करेंगे: http://msdn.microsoft.com/en-us/library/yy12yx1f.aspx

1

क्या _MessageQueue केवल आपके कोड से उपयोग किया जाता है? तो फिर तुम इस तरह एक वर्ग में लपेट कर सकते हैं: जब तक संदेश उपलब्ध है

public class BlockingMessageQueue { 
    private readonly MyMessageQueue queue; 
    private readonly Semaphore signal; 

    public BlockingMessageQueue(MyMessageQueue queue) { 
    this.queue = queue; 
    this.signal = new Semaphore(0, int.MaxValue); 
    } 

    public void Enqueue(IMessage message) { 
    lock (this.queue) { 
     this.queue.Send(message); 
    } 
    this.signal.Release(); 
    } 

    public IMessage Dequeue() { 
    this.signal.WaitOne(); 
    IMessage message; 
    lock (this.queue) { 
     var success = this.queue.GetMessageFromQueue(out message); 
     Debug.Assert(success); 
    } 
    return message; 
    } 
} 

Dequeue को अवरुद्ध कर देगा, इसलिए यदि कोई संदेश उपलब्ध है कोई व्यर्थ चक्र देखते हैं।

प्रयोग उदाहरण:

var queue = new BlockingMessageQueue(_MessageQueue); 

while (true) { 
    var message = queue.Dequeue(); 

    if (message.RoutingInfo == Devices.Common.MessageRoutingInfo.ToDevice) 
    { 
    _Port.SerialPort.WriteLine(message.Message); 
    } 
    else if (message.RoutingInfo == Devices.Common.MessageRoutingInfo.FromDevice) 
    { 
    OnDeviceMessageReceived(new Common.DeviceMessageArgs(message.Message)); 
    } 
} 
+0

आपको बहुत बहुत धन्यवाद, मैं निश्चित रूप से इसे जाने दूंगा। मैं आपको बता दूंगा कि यह कैसा प्रदर्शन करता है। धन्यवाद – AndyMM

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