ConcurrencyMode.Multiple in stateless WCF services

后端 未结 2 1153
南方客
南方客 2021-01-07 08:57

We currently have multiple WCF services which are using the default ServiceBehavior. Due to issues with scalability, we are looking at applying the Concur

相关标签:
2条回答
  • 2021-01-07 09:25

    If your service is stateless and thread safe it is better to use InstanceContextMode.Single combined with ConcurrencyMode.Multiple.

    This will avoid the creation of instances of the service, reduce the memory footprint, reduce GC activity.

    Almost every service I develop is done in this way....

    Unless there was the need to keep separate instances per call or session I would got his way.

    Other answers mention "singleton WCF service - but this is highly discouraged, since it's a) a big hindrance for scalability, and b) extremely tricky to program properly."

    It is NOT highly discouraged, has no impact on scalability ( as a matter of fact can be benefitial ), and there is NOTHIN tricky about it.

    UPDATE: There seems to be confusion about what InstanceContextMode.Single does. This setting will force the WCF engine to create only ONE instance of the service.

    Some people have WRONGLY stated it does not work with basicHttpBinding.

    So I am posting an example to clear this once and for all.

    Here is my Service class:

    using System.ServiceModel;
    
    namespace WcfService1
    {
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class Service1 : IService1
        {
            private int _singleCounter = 0;//this field will be shared across all requests
            public Service1() 
            {
                //this executes only ONCE
            }
            public string GetData()
            {
                //this will increment with each request 
                //because it is a SINGLE instance the count
                //will be preserved
                _singleCounter++;
                return string.Format("Requests on this instance: {0}", _singleCounter);
            }
        }
    }
    

    Here is my service contract:

    using System.ServiceModel;
    
    namespace WcfService1
    {    
        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            string GetData();
        }
    }
    

    This is my config file:

    <?xml version="1.0"?>
    <configuration>
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
      </system.webServer>
    </configuration>
    

    And now some screen shots of the results: This is the first request as you can see the count is 1:

    Now I click again and you can see the count is 2:

    A few clicks later:

    As you can see it is a SINGLE instance keeping a variable across many requests.

    0 讨论(0)
  • 2021-01-07 09:37

    If you use the default "per call" activation mechanism (which works great if your services are completely stateless), there's absolutely no point in adding the ConcurrencyMode.Multiple since each incoming request will get its own instance of the service class to handle its request. This is the preferred and recommended setting for InstanceContextMode.

    Read more about instance management in WCF at MSDN Magazine: Discover Mighty Instance Management Techniques For Developing WCF Apps

    The only time when you benefit from using ConcurrencyMode.Multiple is when you have a singleton WCF service - but this is highly discouraged, since it's a) a big hindrance for scalability, and b) extremely tricky to program properly.

    My recommendation would be: try to narrow down more in detail what really causes the performance problems. Just jumping into ConcurrencyMode.Multiple seems like the wrong approach - it's very messy, very labor-intensive, lots of code, lots of chance of getting it wrong......

    0 讨论(0)
提交回复
热议问题