简体   繁体   English

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

[英]WCF Service Listener to MSMQ - Pending Messages

I've created a WCF service that listens to a private MSMQ for jobs. 我已经创建了一个WCF服务,它可以监听私有MSMQ的作业。 I've throttled my service so that it will only handle one job at a time (maxConcurrentInstances = 1). 我已经限制了我的服务,因此它一次只能处理一个作业(maxConcurrentInstances = 1)。 The problem I have is that when two messages are submitted and I inspect the queue through my Computer Management console, it's empty. 我遇到的问题是,当提交两条消息并通过我的计算机管理控制台检查队列时,它是空的。 I expect there to be one pending message. 我希望有一条待处理的消息。 When I submit three messages, I'll see one pending message in the MSMQ. 当我提交三条消息时,我会在MSMQ中看到一条待处理的消息。 From reading MSDN, it looks like the ServiceHost is holding the next job in memory until the current job is done, but I can't find a way to turn it off so that the it doesn't hold the message in memory. 从阅读MSDN,看起来ServiceHost在内存中保存下一个作业,直到当前作业完成,但是我找不到关闭它的方法,因此它不会将消息保存在内存中。 Does anyone know of a way to make it so that the ServiceHost won't hold the pending message in memory and leave it in the queue? 有没有人知道如何使它成为ServiceHost不会在内存中保留待处理的消息并将其留在队列中? Thanks! 谢谢!

  <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>

I have also noticed this behaviour in netMsmqBinding and as far as I know it's not addressable from the service end. 我也注意到netMsmqBinding中的这种行为,据我所知,它不能从服务端寻址。

This is only an issue if you're not using transactional queues whereby a failure in your service could result in the in-memory message being dropped permanently. 如果您不使用事务性队列,这只是一个问题,因为服务中的故障可能导致内存中的消息被永久删除。

If you use transactional queues even though the message has been read from the inbound queue it's actually still there on the queue (but it becomes "invisible"). 如果您使用事务性队列,即使已从入站队列中读取消息,它实际上仍然在队列中(但它变为“不可见”)。 If you suffer a failure on your service at this time the message will become re-queued and then processed when you come back up. 如果此时您的服务出现故障,则该消息将重新排队,然后在您重新启动时进行处理。

If you cannot use transactional queueing then the only way you can address this is to do so from the client, which means checking to see if a message has been transmitted before making another call. 如果您不能使用事务性排队,那么解决此问题的唯一方法是从客户端执行此操作,这意味着在进行另一次调用之前检查是否已传输消息。 This can be done using System.Messaging or I assume you could bake this into a custom behaviour. 这可以使用System.Messaging来完成,或者我假设您可以将其烘焙为自定义行为。

If you can't use a transactional queue (eg if you are using netMessagingBinding) you can use the ReceiveContext attribute for more fine-grained control. 如果您不能使用事务性队列(例如,如果您使用的是netMessagingBinding),则可以使用ReceiveContext属性进行更细粒度的控制。 Its well explained by Juval Lowy here in his book: 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 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

Also see this MSDN article to see how specifically it can be used in the netMessagingBinding scenario (I know that's not directly relevant to your question but the principal still holds) 另请参阅此MSDN文章,了解它在netMessagingBinding场景中的具体使用方式(我知道这与您的问题没有直接关系,但主体仍然存在)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM