MSMQ触发器调用Windows服务

时间:2012-08-20 16:21:18

标签: windows-services msmq

当队列中有消息时,我需要我的Windows服务来处理队列中的消息。

我当时认为最好设置一个Windows服务,当队列中有消息时,MSMQ应该触发,触发对Windows服务的调用。

有谁知道怎么做?

2 个答案:

答案 0 :(得分:2)

这是一个过于宽泛的问题,但您可以创建一个同步或异步侦听队列的Windows服务,接收消息并在它们到达时对其进行处理。对于如何来实现这一点,Visual Studio提供的默认服务项目是一个良好的开端。从那里你可以创建一个在服务启动时实例化的类,绑定到队列并调用ReceiveBeginReceive(sync或async)来获取消息并处理它们。

另一种选择是使用activation services。从环境角度来看,这可能更复杂,并且您需要某个版本的Windows和.NET才能使用它。

最后是MSMQ触发器。这是(可选)与MSMQ本身一起安装的服务。它可以配置为监视队列并在消息到达时执行操作。这将是最简单的选项,但是如果您选择这个,那么我建议只创建一个普通的EXE而不是服务,并使用触发器来执行它。

This文章介绍了每种方法的一些优缺点;在你做出决定之前,我建议你阅读它。

答案 1 :(得分:2)

如果您愿意,可以在Windows服务中托管WCF ServiceHost,它将在收到消息时自动接收消息。不需要与MSMQ挂钩。 WCF会在消息出现时自动将消息拉入服务。

假设您已经在写MSMQ私有队列'test'了。要编写正在运行的Windows服务,您可以执行此类操作,请原谅服务中方法准确性的示例:

namespace WcfService
{
  public class Order 
  { 
    public int ID { get; set; }
  }

  [ServiceContract]
  public interface IOrderService
  {
    [OperationContract(TransactionScopeRequired=true)]
    void ProcessOrder(Order order);
  }

  public class OrderService : IOrderService
  {
    public void ProcessOrder(Order order)
    {
      Debug.Print("Order ID: ", order.ID);
    }
  }
}

namespace Client
{
  public class WindowsService : IDisposable
  {
    private ServiceHost host = null;

    // TODO: Implement static void Main to initialize service

    // OnStart
    public void OnStart()
    {
      if(host == null)
        host = new ServiceHost( typeof ( OrderService ) );

      host.Open();
    }   

    public void OnStop()
    {
      host.Close();
    }

    public void Dispose()
    {
      // TODO: Implement Dispose() pattern properly
      if(host!=null) 
        host.Dispose();
    }
  }
}

然后配置Windows服务以从MSMQ中读取

<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netMsmqBinding>
                <binding name="readFromQueueBinding" exactlyOnce="false">
                    <security mode="None"/>
                </binding>
            </netMsmqBinding>
        </bindings>
        <services>
            <service name="WcfService.OrderService">
                <endpoint address="net.msmq://localhost/private/test" 
                          binding="netMsmqBinding" 
                          contract="WcfService.IOrderService" 
                          name="IOrderService_Msmq_Service" 
                          bindingConfiguration="readFromQueueBinding"/>
            </service>
        </services>
    </system.serviceModel>
</configuration>