• 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
  • 相关阅读:
    Spring 框架学习:BeanFactory 和 FactoryBean
    Spring框架学习二:通过简单的HelloWorld程序理解IoC
    Spring框架学习一:环境准备
    Java多线程:Condition条件
    Java多线程:公平锁和非公平锁
    Java多线程:AQS源码分析
    Java多线程:可重入锁RentrantLock
    Java多线程:Unsafe 类以及 CAS 函数
    Java多线程:AtomicIntegerFieldUpdater 原子更新字段类
    Java多线程:AtomicReference AtomicStampedReference AtomicMarkableReference 原子更新引用类型
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2783003.html
Copyright © 2020-2023  润新知