2011-05-24 74 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