2

我已经创建了一个从 MSMQueue 读取消息的 Windows 服务,我需要并行执行(两个线程应该同时读取消息)。我怎样才能做到这一点?这是我的代码(几乎是书本):

public partial class MyNewService : ServiceBase
    {
        System.Messaging.MessageQueue mq;
        System.Messaging.Message mes;

        public MyNewService()
        {
            InitializeComponent();

            if (MessageQueue.Exists("MyServer\\MyQueue"))
                mq = new System.Messaging.MessageQueue("MyServer\\MyQueue");

            mq.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
            mq.BeginReceive();

        }

        private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
        {
           try
           {
                MessageQueue mq = (MessageQueue)source;
                Message m = mq.EndReceive(asyncResult.AsyncResult);

                // TODO: Process the m message here

                // Restart the asynchronous receive operation.
                mq.BeginReceive();
            }
            catch(MessageQueueException)
            {
             // Handle sources of MessageQueueException.
            }

            return; 
         }

}

这是我的主要功能:

static class Program
  {
    static void Main()
    {
      ServiceBase[] ServicesToRun;
      ServicesToRun = new ServiceBase[] 
            { 
                new MyNewService() 
            };
      ServiceBase.Run(ServicesToRun);
    }
  }
4

2 回答 2

3

您是否有理由不能只在多个线程上进行处理而不是在多个线程上出列?

这是一个非常基本的实现——它使用ThreadPool队列项目,但是你依赖队列ThreadPool来处理线程数和工作项目数。根据许多其他因素,这可能不适合您的情况。

SetMaxThreads 另外,请注意此处的备注部分。

private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
{
   try
   {
       MessageQueue mq = (MessageQueue)source;
       Message m = mq.EndReceive(asyncResult.AsyncResult);

       // TODO: Process each message on a separate thread
       // This will immediately queue all items on the threadpool,
       // so there may be more threads spawned than you really want
       // Change how many items are allowed to process concurrently using ThreadPool.SetMaxThreads()
       System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(doWork), m);


       // Restart the asynchronous receive operation.
       mq.BeginReceive();
   }
   catch(MessageQueueException)
   {
       // Handle sources of MessageQueueException.
   }

   return; 
}

private static void doWork(object message)
{
    // TODO: Actual implementation here.
}
于 2013-05-08T13:41:56.453 回答
1

I would host a single-threaded instance of the queue reader on multiple windows services.

That way you can increase throughput by spinning up additional services, or throttle back by going back down. It's much simpler than trying to do it all in code.

于 2013-05-08T13:19:35.657 回答