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的调用

procedure TMainForm.StartClick(Sender: TObject);
begin
DSServer.Start;
end;

procedure TMainForm.StopClick(Sender: TObject);
begin
DSServer.Stop;
end;

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

procedure TMainForm.DSServerClassGetClass(DSServerClass: TDSServerClass;
var PersistentClass: TPersistentClass);
begin
DSServerClass.LifeCycle := LifeCycles.Items.Strings[LifeCycles.ItemIndex];
LogMessage(Memo, '生命周期:' + DSServerClass.LifeCycle);
PersistentClass := TSM;
end;

LifeCycles是一个TRadioGroup存放了生命周期使用的三个字符串

最后在OnCreateInstance和OnDestroyInstance事件中记录服务器对象的创建和释放

procedure TMainForm.DSServerClassCreateInstance(
DSCreateInstanceEventObject: TDSCreateInstanceEventObject);
begin
LogMessage(Memo, '服务端对象创建');
end;

procedure TMainForm.DSServerClassDestroyInstance(
DSDestroyInstanceEventObject: TDSDestroyInstanceEventObject);
begin
LogMessage(Memo, '服务端对象释放');
//DSDestroyInstanceEventObject.ServerClassInstance.Free;
end;

效果图

通过Demo我们可以明显的看出三种生命周期的区别 注意切换生命周期需要先停止服务器再启动

但是在我们使用Invocation的时候 会造成内存泄露

打开服务端的ReportMemoryLeaksOnShutdown 调用了两次方法后关闭服务端可以看到如下提示

可以看到服务端对象并没有释放

这里需要我们通过在OnDestroyInstance手动释放

DSDestroyInstanceEventObject.ServerClassInstance.Free;

但是我们会发现内存泄露依然存在TDSProviderDataModuleAdapter依然没有释放

这是由于DataSnap2009中继承自TProviderDataModule的类都使用了适配器模式来支持旧的IAppServer接口

在服务端对象创建的过程TDSServerClass.CreateInstance中我们可以看到

if (Instance <> nil) and Instance.InheritsFrom(TProviderDataModule) then
CreateInstanceEventObject.ServerClassInstance := TDSProviderDataModuleAdapter.Create(Instance);

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

if DestroyInstanceEventObject.ServerClassInstance is TDSProviderDataModuleAdapter then
begin
Adapter := DestroyInstanceEventObject.ServerClassInstance as TDSProviderDataModuleAdapter;
DestroyInstanceEventObject.ServerClassInstance := Adapter.FProviderDataModule;
Adapter.FProviderDataModule := nil;
end else
Adapter := nil;

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

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

附上DEMO源码 DataSnapDemo_3.rar

转载于:https://www.cnblogs.com/MaxWoods/archive/2011/09/23/2187840.html

DataSnap 2009 系列之三 (生命周期篇)相关推荐

  1. Vue 生命周期篇探索 - 第二篇:生命周期-挂载流程

    文章目录 探索学习 Vue 生命周期篇 第二篇:生命周期-挂载流程 以图例分析挂载流程 1. new Vue 2. init Events & Lifecycle 3. beforeCreat ...

  2. Vue 进阶系列丨生命周期

    Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的.若感本文对您有所帮助请点个赞吧! 2013年7月28日,尤雨溪第一次 ...

  3. Vue 生命周期篇探索-第三篇:生命周期-更新流程

    文章目录 探索学习 Vue 生命周期篇 第三篇:生命周期-更新流程 生命周期-更新流程 1. mounted(挂载后) 2. beforeUpdate (更新前) 3. Virtual DOM re- ...

  4. DataSnap 2009 系列之二 (方法篇)

    在过去客户端要调用远程服务器的方法需要通过在TLB里添加接口并且在服务器对象中实现 在DataSnap 2009中调用远程服务器的方法是基于delphi的RTTI机制的 想要一个类允许被远程调用需要做 ...

  5. Compose系列 四 生命周期

    本系列是我学习compose过程中,对官方文档的翻译和解读,以及实验性的Demo工程.主要参考官方文档和中文手册 全部的正文内容(Demo工程除外)源自Compose官方文档,个人解读以引用的形式插入 ...

  6. Android 组件系列-----Activity生命周期

    本篇随笔将会深入学习Activity,包括如何定义多个Activity,并设置为默认的Activity.如何从一个Activity跳转到另一个Activity,还有就是详细分析Activity的生命周 ...

  7. vue使用总结-生命周期篇

    工作之初使用的angularjs框架,从那时开始数据双向绑定的思想就深深的吸引了我.那是刚入门并没有深究angularjs实现双向绑定的原理.所以至今对angularjs也是一知半解.在工作半年左右接 ...

  8. Java高并发编程详解系列-线程生命周期观察者

    引言   在之前的博客中我们知道,Thread提供了很多可获取的状态,以及判断是否alive的方法,但是这些方法都是线程本身提供的,在Runnable运行的过程中所处的状态是无法直接获取到的到,例如什 ...

  9. maven系列:生命周期

    前面我们详细讲解了maven的一大亮点:依赖,maven做为工程大器,还有个特别重要的功能:构建今天我们主要讲解maven的生命周期,maven的生命周期就是对软件项目构建工作的抽象,一个完整的项目构 ...

  10. Spring系列之生命周期回调

    生命周期回调方法 Spring在容器初始化bean之后(完成依赖注入后)和销毁前都提供了回调的方法,我们称之为生命周期的回调方法.Spring中提供了三种方式来完成生命周期的回调. 官网解释 直接看S ...

最新文章

  1. Stuts2的struts.devMode设置成true后,不起作用,仍需要重启tomcat
  2. HBase–常用API操作篇
  3. (1)51单片机NOP指令
  4. Struts2的properties配置文件详解
  5. httpsendrequest的head怎么用string写_商品广告语用怎么写?男人篇
  6. android浮于上方布局,android-在FrameLayout中使RecyclerView上方的视图...
  7. jzoj4228-C【dp】
  8. Java SE 8新功能导览:Java开发世界中的重大变化
  9. WebLogic安装Linux centos7
  10. 织梦留言簿使用及修改
  11. ios 调用系统应用的方法 应用间跳转的方法
  12. Hive thrift服务(将Hive作为一个服务器,其他机器可以作为客户端进行访问)
  13. 云服务器上安装Anaconda3 (亲测有效)
  14. MAC共享目录让WINDOWS访问
  15. linux dd 命令拷贝iso到U盘
  16. amd支持服务器内存,amd专用内存和普通的内存有什么区别?
  17. 基于主从博弈的智能小区代理商定价策略及电动汽车充电管理
  18. html超链接本地链接,为何本地连接变成本地连接2连接
  19. linux va list,vsprintf函数以及va_list使用详解
  20. 《人类简史》《未来简史》读后感作文5000字

热门文章

  1. 计算机外部设备的配置及扩展能力也是计算机,计算机1-6修改后.docx
  2. python在化学中的应用_用Python配平化学方程式的方法
  3. [渝粤教育] 厦门理工学院 模拟电子技术实验 参考 资料
  4. 【渝粤教育】国家开放大学2018年秋季 0008-21T简明现代汉语 参考试题
  5. 【渝粤教育】国家开放大学2018年春季 0390-22T古代诗歌散文专题 参考试题
  6. VIM+LaTexSuite配置
  7. 计算机网络基础系列(二)计算机网络体系结构
  8. 浅谈协方差矩阵 再谈协方差矩阵之主成分分析
  9. HDU 5857 - Median ( 查询模拟 + 思路 )
  10. 学生选课系统,第二版