老老实实学WCF 第八篇 实例化

连接是否是会话对实例化的过程将产生不同的影响。


一、什么是实例化

我们在这里探讨的实例化就是当客户端调用服务端服务方法时,服务端如何对服务类进行实例化的问题。


二、实例化的几种模式

服务端实例化的方式有三种,分别是"每调用实例","每会话实例"和"单一实例"。

1、每调用实例

客户端对服务方法的每一次调用,服务端都会new一个实例,方法调用结束即销毁,这种模式可能要频繁的花费创建对象和销毁对象的花销,因此性能比较差,但是每次调用后服务对象被销毁,对象所把持的资源也就被释放(如文件啦、数据库连接啦),因此伸缩性是最好的。
 服务类上的属性
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

IIS的例子,HelloWCFService.cs的源代码如下:
using System;
using System.ServiceModel;

namespace LearnWCF
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IHelloWCF
    {
        [OperationContract]
        string HelloWCF();
    }

    

     服务器行为(实例上下文模式=实例化上下文模式.每个电话)

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class HelloWCFService : IHelloWCF
    {
        private int _Counter;
        public string HelloWCF()
        {
            _Counter++;
            return "Hello, you called " + _Counter.ToString() + " time(s)";
        }
    }
}


Web.Config配置文件:
只有IIS宿主才支持 wsHttpBinding
<configuration>
  <system.serviceModel>
    <services>
      <service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange">
        <endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataExchange">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


客户端调用:
Hello, you called 1 time(s)
Hello, you called 1 time(s)


结果:
即使我们把服务协定的会话模式设置为Required(必须使用会话),即这个时候服务端和客户端是在进行会话连接的时候,服务端还是为两次客户端调用分别实例化了对象,所以看到计数没有增长,每次都是1。


2、每会话实例

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]


可以看到计数增长了,说明没有实例化新的对象,在整个会话中只有一个。


3、单一实例

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
服务类在受到首次调用的时候实例化,然后一直不销毁,直到服务宿主关闭,在这期间无论是会话连接还是非会话连接,服务端都用这个实例进行调用。这样实际上几乎没有创建和销毁对象的开销,但是如果一旦实例把持资源,则一直都不能释放,毫无伸缩性可言。


关闭客户端程序再运行一次,计数器继续增长了,客户端程序已经重新运行,很显然这是个新的会话,但是服务端的实例一直没有销毁,所以计数器就继续增长了。


在这种模式下,无论我们把协定的SessionMode改成什么值,结果都是一样的,因为服务端已经认准了一个实例,无论客户端连接是不是会话了。

文章出自:http://blog.csdn.net/songyefei/article/details/7405492

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值