WCF服务编程读书笔记(4):实例管理

Example 4-1. The ServiceBehaviorAttribute used to configure instance context mode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WCFServiceProgramming
{
    public enum InstanceContextMode
    {
        PerCall,
        PerSession,
        Single
    }

    [AttributeUsage(AttributeTargets.Class)]
    public sealed class ServiceBehaviorAttribute : Attribute
    {
        public InstanceContextMode InstanceContextMode
        {
            get;
            set;
        }

        // ...
    }
}
View Code

Example 4-2. Per-call service and client(Server)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;

namespace WCFServiceProgramming
{
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    class MyService : IMyContract, IDisposable
    {
        int m_Counter = 0;

        MyService()
        {
            Trace.WriteLine("MyService.MyService()");
        }

        public void MyMethod()
        {
            m_Counter++;
            Trace.WriteLine("Counter = " + m_Counter);
        }

        public void Dispose()
        {
            Trace.WriteLine("MyService.Dispose()");
        }
    }
}
View Code

Example 4-2. Per-call service and client(Client)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    class MyContractClient : ClientBase<IMyContract>, IMyContract
    {
        public void MyMethod()
        {
            Channel.MyMethod();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyContractClient proxy = new MyContractClient();

            proxy.MyMethod();
            proxy.MyMethod();

            proxy.Close();
        }
    }
}
View Code

//Possible Output
MyService.MyService( )
Counter = 1
MyService.Dispose( )
MyService.MyService( )
Counter = 1
MyService.Dispose( )

Example 4-3. Implementing a per-call service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    [DataContract]
    class Param
    { }

    [ServiceContract]
    interface IMyContract
    {
        [OperationContract]
        void MyMethod(Param stateIdentifier);
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    class MyService : IMyContract, IDisposable
    {
        public void MyMethod(Param stateIdentifier)
        {
            GetState(stateIdentifier);
            DoWork();
            SaveState(stateIdentifier);
        }

        private void GetState(Param stateIdentifier)
        {
        }

        private void DoWork()
        {
        }

        private void SaveState(Param stateIdentifier)
        {
        }

        public void Dispose()
        {
        }
    }
}
View Code

Example 4-4. Per-session service and client(Service)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    class MyService : IMyContract, IDisposable
    {
        int m_Counter = 0;

        MyService()
        {
            Trace.WriteLine("MyService.MyService()");
        }

        public void MyMethod()
        {
            m_Counter++;
            Trace.WriteLine("Counter = " + m_Counter);
        }

        public void Dispose()
        {
            Trace.WriteLine("MyService.Dispose()");
        }
    }
}
View Code

Example 4-4. Per-session service and client(Client)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    class MyContractClient : ClientBase<IMyContract>, IMyContract
    {
        public void MyMethod()
        {
            Channel.MyMethod();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyContractClient proxy = new MyContractClient();

            proxy.MyMethod();
            proxy.MyMethod();

            proxy.Close();
        }
    }
}
View Code

//Output
MyService.MyService( )
Counter = 1
Counter = 2
MyService.Dispose( )

Example 4-5. Enabling reliability for per-session services(Host Configuration)

<?xml version="1.0"?>

<configuration>

  <system.web>
    <compilation debug="false" targetFramework="4.0" />
  </system.web>

  <!-- Host Configuration -->
  <system.serviceModel>
    <services>
      <service name="MyPerSessionService">
        <endpoint 
          address="net.tcp://localhost:8000/MyPerSessionService" 
          binding="netTcpBinding" 
          bindingConfiguration="TCPSession"
          contract="IMyContract"
        />
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="TCPSession">
          <reliableSession enabled="true"/>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>

</configuration>
View Code

Example 4-5. Enabling reliability for per-session services(Client Configuration)

<?xml version="1.0"?>

<configuration>

  <system.web>
    <compilation debug="false" targetFramework="4.0" />
  </system.web>

  <!-- Client Configuration -->
  <system.serviceModel>
    <client>
      <endpoint 
        address="net.tcp://localhost:8000/MyPerSessionService" 
        binding="netTcpBinding" 
        bindingConfiguration="TCPSession" 
        contract="IMyContract"/>
    </client>
    <bindings>
      <netTcpBinding>
        <binding name="TCPSession">
          <reliableSession enabled="true"/>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>

</configuration>
View Code

Example 4-6. A singleton service and client(Service)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    ///////////////////////// Service code /////////////////////
    [ServiceContract(SessionMode = SessionMode.Required)]
    interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    [ServiceContract(SessionMode = SessionMode.NotAllowed)]
    interface IMyOtherContract
    {
        [OperationContract]
        void MyOtherMethod();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    class MySingleton : IMyContract, IMyOtherContract, IDisposable
    {
        int m_Counter = 0;

        public MySingleton()
        {
            Trace.WriteLine("MySingleton.MySingleton( )");
        }
        public void MyMethod()
        {
            m_Counter++;
            Trace.WriteLine("Counter = " + m_Counter);
        }
        public void MyOtherMethod()
        {
            m_Counter++;
            Trace.WriteLine("Counter = " + m_Counter);
        }
        public void Dispose()
        {
            Trace.WriteLine("Singleton.Dispose( )");
        }
    }
}
View Code

Example 4-6. A singleton service and client(Client) 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WCFServiceProgramming
{
    ///////////////////////// Client code /////////////////////
    class MyContractClient : ClientBase<IMyContract>, IMyContract
    {
        public void MyMethod()
        {
            Channel.MyMethod();
        }
    }

    class MyOtherContractClient : ClientBase<IMyOtherContract>, IMyOtherContract
    {
        public void MyOtherMethod()
        {
            Channel.MyOtherMethod();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyContractClient proxy1 = new MyContractClient();
            proxy1.MyMethod();
            proxy1.Close();

            MyOtherContractClient proxy2 = new MyOtherContractClient();
            proxy2.MyOtherMethod();
            proxy2.Close();
        }
    }
}
View Code

//Output
MySingleton.MySingleton( )
Counter = 1
Counter = 2

Example 4-7. Initializing and hosting a singleton (Service)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace WCFServiceProgramming.Library
{
    ///////////////////////// Service code /////////////////////
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class MySingleton : IMyContract, IDisposable
    {
        int m_Counter = 0;

        public int Counter
        {
            get
            {
                return m_Counter;
            }
            set
            {
                m_Counter = value;
            }
        }

        public void MyMethod()
        {
            m_Counter++;
            Trace.WriteLine("Counter = " + m_Counter);
        }
    }
}
View Code

Example 4-7. Initializing and hosting a singleton (Host)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFServiceProgramming.Library;
using System.ServiceModel;

namespace WCFServiceProgramming.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            MySingleton singleton = new MySingleton();
            singleton.Counter = 42;

            ServiceHost host = new ServiceHost(singleton);
            host.Open();
            // Do some blocking calls then
            host.Close();
        }
    }
}
View Code

Example 4-7. Initializing and hosting a singleton (Client)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;
using WCFServiceProgramming.Library;

namespace WCFServiceProgramming.Client
{
    ///////////////////////// Client code /////////////////////
    class MyContractClient : ClientBase<IMyContract>, IMyContract
    {
        public void MyMethod()
        {
            Channel.MyMethod();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyContractClient proxy = new MyContractClient();
            proxy.MyMethod();
            proxy.Close();
        }
    }
}
View Code

Example 4-8. Using ReleaseServiceInstance( )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace WCFServiceProgramming.Library
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IMyContract
    {
        [OperationContract]
        void MyMethod();
    }

    public class MyService : IMyContract, IDisposable
    {
        public void MyMethod()
        {
            //Do some work then
            OperationContext.Current.InstanceContext.ReleaseServiceInstance();
        }

        public void Dispose()
        { }
    }
}
View Code

Example 4-9. Administrative throttling

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="MyService" behaviorConfiguration="ThrottleBehavior">
        
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ThrottleBehavior">
          <serviceThrottling 
            maxConcurrentCalls="12" 
            maxConcurrentSessions="34" 
            maxConcurrentInstances="56"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
View Code

Example 4-10. Programmatic throttling

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFServiceProgramming.Library;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCFServiceProgramming.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(MyService));

            ServiceThrottlingBehavior throttle;
            throttle = host.Description.Behaviors.Find<ServiceThrottlingBehavior>();

            if (throttle == null)
            {
                throttle = new ServiceThrottlingBehavior();
                throttle.MaxConcurrentCalls = 12;
                throttle.MaxConcurrentSessions = 34;
                throttle.MaxConcurrentInstances = 56;

                host.Description.Behaviors.Add(throttle);
            }

            host.Open();
            // Do some blocking calls then
            host.Close();
        }
    }
}
View Code

Example 4-11. Extending ServiceHost<T> to handle throttling

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Diagnostics;
using System.ServiceModel.Channels;

namespace WCFServiceProgramming.Host
{
    public class ServiceHost<T> : ServiceHost
    {
        public void SetThrottle(int maxCalls, int maxSessions, int maxInstances)
        {
            ServiceThrottlingBehavior throttle = new ServiceThrottlingBehavior();
            throttle.MaxConcurrentCalls = maxCalls;
            throttle.MaxConcurrentSessions = maxSessions;
            throttle.MaxConcurrentInstances = maxInstances;

            SetThrottle(throttle);
        }

        private void SetThrottle(ServiceThrottlingBehavior throttle)
        {
            SetThrottle(throttle, false);
        }

        private void SetThrottle(ServiceThrottlingBehavior serviceThrottle, bool overrideConfig)
        {
            if (State == CommunicationState.Opened)
            {
                throw new InvalidOperationException("Host is already opened");
            }

            ServiceThrottlingBehavior throttle = Description.Behaviors.Find<ServiceThrottlingBehavior>();
            
            if (throttle != null && overrideConfig == false)
            {
                return;
            }

            if (throttle != null) //overrideConfig == true, remove the configured one
            {
                Description.Behaviors.Remove(throttle);
            }

            if (throttle == null)
            {
                Description.Behaviors.Add(serviceThrottle);
            }
        }

        public ServiceThrottlingBehavior ThrottleBehavior
        {
            get 
            {
                return Description.Behaviors.Find<ServiceThrottlingBehavior>();
            }
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/thlzhf/p/2783003.html