我创建了一个WCF服务,用于侦听私有MSMQ的作业。我已经限制了我的服务,因此它一次只能处理一个作业(maxConcurrentInstances = 1)。我遇到的问题是,当提交两条消息并通过我的计算机管理控制台检查队列时,它是空的。我希望有一条待处理的消息。当我提交三条消息时,我会在MSMQ中看到一条待处理的消息。从阅读MSDN,看起来ServiceHost在内存中保存下一个作业,直到当前作业完成,但是我找不到关闭它的方法,因此它不会将消息保存在内存中。有没有人知道如何使它成为ServiceHost不会在内存中保留待处理的消息并将其留在队列中?谢谢!
<configuration>
<system.serviceModel>
<services>
<service
name="MyService"
behaviorConfiguration="DefaultServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/MyService/"/>
</baseAddresses>
</host>
<endpoint
address="net.msmq://localhost/private/MyService"
binding="netMsmqBinding" bindingConfiguration="MsmqBindingNoSecurity"
contract="IMyService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceThrottling
maxConcurrentCalls="1"
maxConcurrentSessions="1"
maxConcurrentInstances="1"
/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netMsmqBinding>
<binding name="MsmqBindingNoSecurity"
useActiveDirectory="false"
exactlyOnce="false">
<security mode="None">
<transport
msmqAuthenticationMode="None"/>
</security>
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>
</configuration>
答案 0 :(得分:0)
我也注意到netMsmqBinding中的这种行为,据我所知,它无法从服务端寻址。
如果您没有使用事务性队列,这只是一个问题,因为服务中的故障可能导致内存中的消息被永久删除。
如果您使用事务性队列,即使已从入站队列中读取消息,它实际上仍然在队列中(但它变为“不可见”)。如果此时您的服务出现故障,则该消息将重新排队,然后在您重新启动时进行处理。
如果您不能使用事务性排队,那么解决此问题的唯一方法是从客户端执行此操作,这意味着在进行另一次调用之前检查是否已传输消息。这可以使用System.Messaging来完成,或者我假设您可以将其烘焙为自定义行为。
答案 1 :(得分:0)
如果您不能使用事务性队列(例如,如果您使用的是netMessagingBinding),则可以使用ReceiveContext属性进行更细粒度的控制。 Juval Lowy在他的书中很好地解释了这一点:
另请参阅此MSDN文章,了解它在netMessagingBinding场景中的具体使用方式(我知道这与您的问题没有直接关系,但校长仍然有效)
http://msdn.microsoft.com/en-us/library/hh532034(VS.103).aspx