2

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

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

有谁知道如何做到这一点?

4

2 回答 2

2

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

另一种选择是使用激活服务。从环境角度来看,这可能更复杂,您需要特定版本的 Windows 和 .NET 才能使用它。

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

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

于 2012-08-20T17:23:36.960 回答
2

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

假设您已经在写入 MSMQ 私有队列“测试”。要编写正在运行的 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>
于 2012-08-27T11:14:33.487 回答