2011-05-24 3 views
4

J'ai un service Windows qui lit ma file d'attente de messages via WCF. Je veux que le service traite un message avant un autre message (actions intensives de mémoire par msg). J'ai mis la configuration d'étranglement à 1, mais cela ne semble pas faire quoi que ce soit. Si j'ai 6 messages dans ma file d'attente, il en faut 4 juste après le début.MSMQ WCF Throttling

Ai-je raté quelque chose?

Mon web.config:

<system.serviceModel> 
<client> 
    <endpoint 
    address="net.tcp://spserv30:9999/services/SPInterface" 
    binding="netTcpBinding" bindingConfiguration="tcpspbinding" 
    contract="Itineris.OPM.WCFSP.ActionContracts.ISPActions" > 
    </endpoint> 
</client> 
<services> 
    <service name="Itineris.OPM.MSMQProcessorV2.MSMQProcessor" behaviorConfiguration="Throttled" > 
    <endpoint address="msmq.formatname:DIRECT=OS:localhost\private$\documents" binding="msmqIntegrationBinding" 
       bindingConfiguration="MSMQProcessorBinding" contract="Itineris.OPM.MSMQProcessorV2.IMSMQProcessor" /> 
    </service> 
</services> 
<bindings> 
    <netTcpBinding> 
    <binding name="tcpspbinding" transferMode="StreamedRequest" /> 
    </netTcpBinding> 
    <msmqIntegrationBinding> 
    <binding name="MSMQProcessorBinding" maxReceivedMessageSize="2147483647" 
      receiveRetryCount="0" retryCycleDelay="00:10:00" maxRetryCycles="0" 
      receiveErrorHandling="Move"> 
     <security mode="None" /> 
    </binding> 
    </msmqIntegrationBinding> 


    </bindings> 
<behaviors> 
     <serviceBehaviors> 
     <behavior name="Throttled"> 
      <serviceThrottling 
      maxConcurrentCalls="1" 
      maxConcurrentSessions="1" 
      maxConcurrentInstances="1" 
      /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

Ma création ServiceHost:

protected override void OnStart(string[] args) 
    { 

      if (_serviceHost != null) 
      { 
       if (_serviceHost.State != CommunicationState.Faulted) 
        _serviceHost.Close(); 
       else 
        _serviceHost.Abort(); 
      } 
      //create servicehost 
      _serviceHost = new ServiceHost(typeof(MSMQProcessor)); 
      _serviceHost.Open(); 
      _serviceHost.Faulted += serviceHost_Faulted; 

      // Already load configuration here so that service does not start if there is a configuration error. 
      new DocumentGeneratorV2.LoadGeneratorConfigurator().Load(); 

      var startLog = new LogEntry {Message = "Itineris MSMQ Processor Service V2 has started"}; 
      startLog.Categories.Add(CategoryGeneral); 
      startLog.Priority = PriorityNormal; 

      Logger.Write(startLog); 






    } 

    private void serviceHost_Faulted(object sender, EventArgs e) 
    { 
     if (!_isClosing) 
     { 
      _serviceHost.Abort(); 
      _serviceHost = new ServiceHost(typeof(MSMQProcessor)); 
      _serviceHost.Faulted += serviceHost_Faulted; 
      _serviceHost.Open(); 
     } 
    } 

classe avec contrat:

[ServiceContract(Namespace = "http://Itineris.DocxGenerator.MSMQProcessor")] 
[ServiceKnownType(typeof(string))] 
public interface IMSMQProcessor 

{ 
    [OperationContract(IsOneWay = true, Action = "*")] 
    void GenerateWordDocument(MsmqMessage<string> message); 
} 

public class MSMQProcessor : IMSMQProcessor 
{ 
    /// <summary> 
    /// Method that processed the message and generates a word document 
    /// </summary> 
    /// <param name="message">message from MSMQ to be processed</param> 
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 
    public void GenerateWordDocument(MsmqMessage<string> message) 
    { 
     DocumentGeneration documentGenerator = null; 
     var state = new DocumentStatus(); 
     var docGenerator = new DocumentGenerator(new LoadGeneratorConfigurator().Load()); 


      var deserializer = new XmlSerializer(typeof(DocumentGeneration)); 

      documentGenerator = deserializer.Deserialize(new StringReader(message.Body)) as DocumentGeneration; 
      if(documentGenerator == null) 
       throw new Exception("Deserializing of the message has failed"); 

      docGenerator.MailQueue = appSettings["MAILQUEUE"]; 
      docGenerator.GenerateDocument(documentGenerator); 


      var builder = new StringBuilder(); 
      builder.Append("The documents have been saved to the following locations: \r\n"); 

      } 
      } 
+0

Vous ne l'avez pas mis des informations clés sur votre configuration de service dans la question: qu'est-ce que l'attribut ServiceBehavior pour la classe de mise en œuvre de service contient et ce qui fait les ServiceModel> comportements> élément ServiceBehavior nommé " Étranglé "contenir. Je ne peux vraiment rien suggérer sans cette information. –

+0

Désolé sur la section "Throttled", doit avoir eu une copie périmée de la question. L'attribut ServiceBehavior pour la classe d'implémentation est toujours nécessaire cependant. –

+0

J'ai ajouté ma classe d'implémentation, désolé pour le morceau manquant. Est-il nécessaire de spécifier servicebehavior dans la classe quand il est spécifié dans la config? – Rogue101

Répondre

3

Votre service tel que configuré dans la question devrait uniquement un message de processus à une fois. Bien que vous n'utilisiez pas l'attribut ServiceBehavior pour la classe d'implémentation de service, la valeur par défaut de ConcurrencyMode est Single not Multiple (ce qui peut provoquer le comportement que vous voyez). La valeur par défaut de InstanceContextMode est Par session, mais les valeurs maxConcurrentInstances et maxConcurrentSessions forcent le support pour une seule session à la fois.

La seule autre option que je vois est de forcer le ServiceHost à utiliser une seule instance de service en utilisant un constructeur différent. Voici le code:

// ... snipped ... 

//force single service instance to be used by servicehost 
var singleton = new MSMQProcessor(); 
_serviceHost = new ServiceHost(singleton); 
_serviceHost.Open(); 


// ... snipped ... 
+0

Je l'ai fait travailler avec l'option ci-dessus et la configurer sur mes méthodes, au lieu d'utiliser le fichier de configuration. Merci pour l'aide! – Rogue101