InstanceContextMode.Single доступен для WCF basicHttpBinding? - PullRequest
0 голосов
/ 19 марта 2020

Как я понял из этой статьи :

Single: это поможет нам обмениваться данными в глобальном масштабе. Мы можем создать только один экземпляр, и этот же экземпляр будет повторно использован при последующих вызовах. Как и в случае с сеансом, это будет работать со всеми привязками, кроме basicHttpBinding.

InstanceContextMode.Single недоступно для basicHttpBinding.

Но согласно этот ответ работает.

Эта статья добавляет путаницу.

Я хотел бы получить четкий ответ и объяснение.

1 Ответ

1 голос
/ 20 марта 2020

InstanceContextMode.Single заставит механизм WCF создать один экземпляр вашего класса обслуживания в течение срока службы вашего сервиса. Это означает, что все запросы будут использовать один и тот же экземпляр, а не создавать его для каждого запроса.

Это вполне возможно с basicHttpBinding.

Вот пример использования basicHttpBinding и InstanceContextMode.Single:

Сначала мой класс Service, который имеет приватное поле, в котором хранится количество запросов:

using System.ServiceModel;

namespace WcfService1
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class Service1 : IService1
    {
        private int _singleCounter = 0;//this will be preserved across requests
        public Service1() 
        {
            //this constructor 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);
        }
    }
}

Теперь мой контракт на обслуживание:

using System.ServiceModel;

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

Наконец, вот мой конфигурационный файл с одним привязка с использованием basicHttpBinding:

<?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>

Теперь с помощью стандартного тестового клиента WCF, поставляемого с Visual Studio, приведены следующие результаты:

При первом вызове счетчик равен 1: enter image description here

Второй вызов - 2: enter image description here

Через несколько щелчков счет сохраняется: enter image description here

Я не уверен, почему в некоторых статьях говорится, что InstanceContextMode.Single не поддерживается basicHttpBinding. Это, очевидно, неверно.

Я использую InstanceContextMode.Single в сочетании с ConcurrencyMode.Multiple для служб с высокой пропускной способностью все время.

Он также имеет то преимущество, что вы можете сохранять некоторое «состояние» во время время жизни службы, которая может использоваться всеми запросами. Например, я храню часто используемые данные в приватных полях, чтобы не загружать их из базы данных при каждом запросе и т. Д. c.

...