Welcome

首页 / 软件开发 / WCF / WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[中篇]

WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[中篇]2012-11-20 cnblogs Artech在[第1篇]中,我们介绍了WCF关于实例管理一些基本的知识点,包括InstanceContext、InstanceContextMode、已经如何通过ServiceBehaviorAttribute应用不同的实例上下文模式给不同的服务。在[第1篇]中,对WCF采用的三种不同实例上下文模式进行了简单的比较,本篇的重点方法对单调(PerCall)模式为进行详细介绍。

在单调(Per-Call)实例上下文模式下,WCF总是创建一个新的服务实例上下文处理接收到的每一个服务调用请求,并在服务操作执行结束后,回收服务上下文和服务实例。换句话说,单调服务实例上下文模式使服务实例上下文的生命周期与服务调用本身绑定。我们首先来介绍单调模式下服务实例上下文具体有怎样的生命周期。

一、 单调模式下的服务实例上下文提供机制

对于单调模式,服务实例的生命周期大体上可以看成服务操作执行的生命周期。服务实例在服务操作执行前被创建,在操作完成之后被回收。下面的列表揭示了在单调模式下,对于每一次服务调用请求,WCF的整个服务实例激活过程:

WCF服务端接收到来自客户端的服务调用请求;

通过实例上下文提供者(InstanceContextProvider)对象试图获取现有服务实例的实例上下文,对于单调模式,返回的实例上下文永远为空;

如果获取实例上下文为空,则通过实例提供者(IntanceProvider)创建服务实例,封装到新创建的实例上下文中;

通过InstanceContext的GetServiceInstance方法获取服务实例对象,借助操作选择器(OperationSelector)选择出相应的服务操作,最后通过操作执行器(OperationInvoker)对象执行相应的操作方法;

操作方法执行完毕后,关闭被卸载InstanceContext对象。在此过程中,会调用InstanceProvider对象释放服务实例,如果服务类型实现了接口IDisposable,则会调用Disposable方法;

服务实例成为垃圾对象,等待GC回收。

对于上述列表中提到的InstanceContextProvider、InstanceProvider等重要的对象,以及相关的实现机制,将在本系列后续的部分进行单独讲解。为了加深读者的理解,这里通过一个简单的例子来演示在单调模式下服务实例的整个激活流程。

二、 实例演示:单调模式下服务实例的生命周期

本案例依然沿用典型的4层结构和计算服务的场景,下面是服务契约和具体服务实现的定义。在CalculatorService类型上,通过ServiceBehaviorAttribute特性将实例上下文模式设为单调(Per-Call)模式。为了演示服务实例的创建、释放和回收,我们分别定义了无参构造函数,终止化器(Finalizer)以及实现的接口IDisposable,并在所有的方法中输出相应的指示性文字,以便更容易地观测到它们执行的先后顺序。

 1: using System.ServiceModel;
2: namespace Artech.WcfServices.Contracts
3: {
4: [ServiceContract(Namespace="http://www.artech.com/")]
5: public interface ICalculator
6: {
7: [OperationContract]
8: double Add(double x, double y);
9: }
10: }
1: using System;
2: using System.ServiceModel;
3: using Artech.WcfServices.Contracts;
4: namespace Artech.WcfServices.Services
5: {
6: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
7: public class CalculatorService : ICalculator, IDisposable
8: {
9: public CalculatorService()
10: {
11: Console.WriteLine("Service object is instantiated.");
12: }
13: ~CalculatorService()
14: {
15: Console.WriteLine("Service object is finalized.");
16: }
17:
18: public void Dispose()
19: {
20: Console.WriteLine("Service object is disposed.");
21: }
22: public double Add(double x, double y)
23: {
24: Console.WriteLine("Operation method is invoked.");
25: return x + y;
26: }
27: }
28: }
为了演示GC对服务实例的回收,在进行服务寄宿的时候,通过System.Threading.Timer使GC每隔10毫秒强制执行一次垃圾回收。

 1: using System;
2: using System.ServiceModel;
3: using System.Threading;
4: using Artech.WcfServices.Services;
5: namespace Artech.WcfServices.Hosting
6: {
7: public class Program
8: {
9: private static Timer GCScheduler;
10:
11: static void Main(string[] args)
12: {
13: GCScheduler = new Timer(
14: delegate
15: {
16: GC.Collect();
17: }, null, 0, 100);
18: using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
19: {
20: serviceHost.Open();
21: Console.Read();
22: }
23: }
24: }
25: }