2011-05-24 71 views
4

我有一個通過WCF讀取我的消息隊列的Windows服務。我希望服務在另一條消息之前處理一條消息(每個消息密集記憶操作)。我將限制配置設置爲1,但似乎沒有任何操作。如果我的隊列中有6條消息,啓動後需要4條消息。MSMQ WCF節流

我錯過了什麼?

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

我的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(); 
     } 
    } 

類合同:

[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

你還沒有把你的服務配置到問題的一些關鍵信息:什麼是對服務實現類的ServiceBehavior屬性包含:什麼是serviceModel>行爲> serviceBehavior元素命名爲「節流「包含。如果沒有這些信息,不能真正提出任何建議。 – 2011-05-24 15:30:46

+0

對不起,在「節流」部分,必須有一個陳舊的問題副本。儘管實現類的ServiceBehavior屬性仍然需要。 – 2011-05-24 15:48:48

+0

我已經添加了我的實現類,對於缺少的部分感到抱歉。在配置文件中指定時,是否有必要在類中指定servicebehavior? – Rogue101 2011-05-25 07:16:17

回答

3

的配置問題你的服務應該僅在處理消息一次。雖然您沒有爲服務實現類使用ServiceBehavior屬性,但併發模式的默認值爲Single not Multiple(這可能會導致您所看到的行爲)。 InstanceContextMode的默認值是Per Session,但maxConcurrentInstances和maxConcurrentSessions值一次強制支持單個會話。

我看到的唯一的其他選項是通過使用不同的構造函數強制ServiceHost只使用一個服務實例。下面是代碼:

// ... snipped ... 

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


// ... snipped ... 
+0

我得到它與上面的選項一起工作,並配置它在我的方法,而不是使用配置文件。謝謝您的幫助! – Rogue101 2011-06-07 07:42:04