MSMQ的WCF服务侦听器 - 待处理消息

时间:2012-10-31 05:01:42

标签: wcf msmq

我创建了一个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>

2 个答案:

答案 0 :(得分:0)

我也注意到netMsmqBinding中的这种行为,据我所知,它无法从服务端寻址。

如果您没有使用事务性队列,这只是一个问题,因为服务中的故障可能导致内存中的消息被永久删除。

如果您使用事务性队列,即使已从入站队列中读取消息,它实际上仍然在队列中(但它变为“不可见”)。如果此时您的服务出现故障,则该消息将重新排队,然后在您重新启动时进行处理。

如果您不能使用事务性排队,那么解决此问题的唯一方法是从客户端执行此操作,这意味着在进行另一次调用之前检查是否已传输消息。这可以使用System.Messaging来完成,或者我假设您可以将其烘焙为自定义行为。

答案 1 :(得分:0)

如果您不能使用事务性队列(例如,如果您使用的是netMessagingBinding),则可以使用ReceiveContext属性进行更细粒度的控制。 Juval Lowy在他的书中很好地解释了这一点:

http://books.google.co.uk/books?id=PvNrurEhmiEC&pg=PA500&lpg=PA500&dq=ReceiveContext&source=bl&ots=ChDvHuH_Jq&sig=XHhiz2ebmXuu0QNYcBYhtlN99p4&hl=en&sa=X&ei=XgYmUo3kHOOH0AW--oHoCg&ved=0CFsQ6AEwCTgK#v=onepage&q=ReceiveContext&f=false

另请参阅此MSDN文章,了解它在netMessagingBinding场景中的具体使用方式(我知道这与您的问题没有直接关系,但校长仍然有效)

http://msdn.microsoft.com/en-us/library/hh532034(VS.103).aspx