繁体   English   中英

监视队列的最有效方法

[英]Most efficient way to monitor a queue

监视队列的最有效方法是什么。

以下代码是最大的资源:

/// <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));
                }
            }
        }
    }
}

Start Service在后台线程上运行,对_MessageQueue.Count的调用不是线程安全的,我没有锁定MessageQueue中的count。 但是我确实锁定了_MessageQueue.GetMessageFromQueue的实现。 我这样做有效吗? 我是否应该提高事件每次队列从0到大于0?

您可能应该在该方法中包含某种类型的线程休眠,否则它将使用100%的CPU。 或者,您可以创建一个等待句柄,并在向队列添加消息时进行设置。

如果我没有错过任何东西 - 你正忙着等待_messageQueue.Count属性。 我会尝试做类似的事情: http//msdn.microsoft.com/en-us/library/yy12yx1f.aspx

您可以使用NetMsmqBinding直接将MSMQ消息直接用于WCF,而不是主动轮询队列

http://msdn.microsoft.com/en-us/library/ms789008.aspx

希望这可以帮助。

_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));
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM