4

WCF を介してメッセージ キューを読み取る Windows サービスがあります。サービスが別のメッセージの前に 1 つのメッセージを処理するようにします (メッセージごとの集中的なメモリ アクション)。スロットリング構成を 1 に設定しましたが、何もしていないようです。キューに 6 つのメッセージがある場合、開始直後に 4 つかかります。

何か不足していますか?

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

私のサービスホストの作成:

  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");

            }
            }
4

1 に答える 1

3

質問で構成されているサービスは、一度にメッセージのみを処理する必要があります。サービス実装クラスに ServiceBehavior 属性を使用していませんが、ConcurrencyMode のデフォルト値は Multiple ではなく Single です (これにより、表示されている動作が発生する可能性があります)。InstanceContextMode のデフォルト値は Per Session ですが、maxConcurrentInstances と maxConcurrentSessions の値は一度に 1 つのセッションのサポートを強制します。

私が目にする他の唯一のオプションは、別のコンストラクターを使用して ServiceHost が 1 つのサービス インスタンスのみを使用するようにすることです。コードは次のとおりです。

// ... snipped ...

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


// ... snipped ...
于 2011-05-25T12:53:01.840 に答える