DataSnap 2009 系列之三 (生命周期篇)

简介: (生命周期篇)  DataSnap 2009的服务器对象的生命周期依赖于DSServerClass组件的设置,当DSServer启动时从 DSServerClass组件读取LifeCycle属性的值。

(生命周期篇)

  DataSnap 2009的服务器对象的生命周期依赖于DSServerClass组件的设置,当DSServer启动时从 DSServerClass组件读取LifeCycle属性的值。

  注意:LifeCycle的值由于在启动时就已经读取 启动后再修改LifeCycle的值将没有任何效果,LifeCycle属性的值可以是以下三种字符串之一。

   1.Session

  该选项为默认设置,每个连接都会建立一个独立的服务器对象为客户端提供服务,服务器对象在连接关闭后释放,因此多个客户端访问的是不同的服务器对象,是线程安全的。

  2.Invocation

  对于每次服务端方法调用建立一个独立的服务器对象为客户端提供服务,服务器对象在调用结束后释放,这个同样也是线程安全的,但是每次调用都创建和释放服务器对象对于频繁调用的系统影响很大,如果把服务端对象用对象池管理配合此种方式将是个非常不错的解决方案。

   3.Server

  所有的客户端使用同一个服务端对象,也就是该对象是单例的,需要开发人员自己来进行同步的控制,不是线程安全的。在服务端对象创建和释放时将触发DSServerClass的两个重要的事件OnCreateInstance和 OnDestroyInstance。在这里我们可以使用自定义创建和释放服务器对象 同样我们可以用于服务端对象池,下面我们把上一次的DEMO稍微改动下来观察下服务端对象的生命周期。

  我们先将DSServer组件的AutoStart设置为 False 然后拖上两个Button分别完成Start和Stop的调用

  在OnGetClass中记录服务启动时使用的生命周期

  LifeCycles是一个TRadioGroup存放了生命周期使用的三个字符串,最后在OnCreateInstance 和OnDestroyInstance事件中记录服务器对象的创建和释放。

  效果图

  通过Demo我们可以明显的看出三种生命周期的区别 注意切换生命周期需要先停止服务器再启动,但是在我们使用Invocation的时候 会造成内存泄露,打开服务端的 ReportMemoryLeaksOnShutdown 调用了两次方法后关闭服务端可以看到如下提示:

  可以看到服务端对象并没有释放,这里需要我们通过在OnDestroyInstance手动释放。

DSDestroyInstanceEventObject.ServerClassInstance.Free;

  但是我们会发现内存泄露依然存在TDSProviderDataModuleAdapter依然没有释放,这是由于 DataSnap2009中继承自TProviderDataModule的类都使用了适配器模式来支持旧的IAppServer接口,在服务端对象创建的过程TDSServerClass.CreateInstance中我们可以看到。

  因此在服务端释放的TDSServerClass.DestroyInstance中需要释放 TDSProviderDataModuleAdapter对象

  当使用Invocation生命周期时 传递的ServerClassInstance并不是TDSProviderDataModuleAdapter的对象

  所以尽管我们手动释放了我们的服务端对象 适配器对象任然造成了内存泄露

相关文章
|
缓存 .NET 图形学
WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成
原文:WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成 在这之前,我写过深入介绍MS EnterLib PIAB的文章(参阅《MS Enterprise Library Policy Injection Application Block 深入解析[总结篇]》),...
893 0
|
XML .NET 数据格式
WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?
原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源。同理,一个WCF服务的监听与执行同样需要通过一个进程来承载。
720 0
|
XML 数据格式 网络架构
WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
原文:WCF技术剖析之二十一:WCF基本异常处理模式[中篇] 通过WCF基本的异常处理模式[上篇], 我们知道了:在默认的情况下,服务端在执行某个服务操作时抛出的异常(在这里指非FaultException异常),其相关的错误信息仅仅限于服务端可见,并不会被WCF传递到客户端;如果将开启了IncludeExceptionDetailInFaults的ServiceDebug服务行为通过声明(通过在服务类型上应用ServiceBehaviorAttrite特性)或者配置的方式应用到相应的服务上,异常相关的所有细节信息将会原封不动地向客户端传送。
757 0
下一篇
无影云桌面