4

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

2 回答 2

0

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

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

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

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

于 2012-11-13T10:14:26.633 回答
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=onepage&q=

另请参阅此 MSDN 文章以了解它在 netMessagingBinding 场景中的具体用途(我知道这与您的问题没有直接关系,但主体仍然成立)

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

于 2013-09-03T16:09:16.540 回答