【发布时间】:2012-08-16 00:04:36
【问题描述】:
当队列中有消息时,我需要我的 Windows 服务来处理队列中的消息。
我在想最好设置一个 Windows 服务,当队列中有消息时,MSMQ 应该触发,触发对 Windows 服务的调用。
有人知道怎么做吗?
【问题讨论】:
标签: windows-services msmq
当队列中有消息时,我需要我的 Windows 服务来处理队列中的消息。
我在想最好设置一个 Windows 服务,当队列中有消息时,MSMQ 应该触发,触发对 Windows 服务的调用。
有人知道怎么做吗?
【问题讨论】:
标签: windows-services msmq
这是一个过于宽泛的问题,但您可以创建一个 Windows 服务来同步或异步侦听队列、接收消息并在消息到达时对其进行处理。至于如何实现这一点,Visual Studio 提供的默认服务项目是一个好的开始。从那里您可以创建一个在服务启动时实例化的类,绑定到队列并调用Receive 或BeginReceive(同步或异步)来获取消息并处理它们。
另一种选择是使用activation services。从环境角度来看,这可能更复杂,您需要特定版本的 Windows 和 .NET 才能使用它。
最后是 MSMQ 触发器。这是一项与 MSMQ 本身一起(可选)安装的服务。它可以配置为监视队列并在消息到达时执行操作。这将是最简单的选项,但是如果您选择此选项,那么我建议您只创建一个普通的 EXE 而不是服务,并使用触发器来执行它。
This 文章涵盖了每种方法的一些优缺点;我建议您在做出决定之前阅读它。
【讨论】:
如果您愿意,您可以在 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();
}
}
}
然后配置从 MSMQ 读取的 Windows 服务
<?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>
【讨论】: