`
阿尔萨斯
  • 浏览: 4472048 次
社区版块
存档分类
最新评论

COM+编程研究之对象池、JITA

 
阅读更多
你有没有在开发COM+组件?你明白COM与COM+的区别么?你有没有在使用COM+的对象池,你有没有碰到过不能远程调试的问题?或者当你在一个COM+组件内部缓存了另一个组件接口指针时,你有没有遇到一些奇怪的现象?
我正在开发COM+组件,我以前常常遇到一些奇怪的现象(当我运用对象池和JITA时),我查阅了一些书籍,找到了原因,但是现有的书籍总是不能详细的指导编程。所以,我今天打算将自己的所学和所用作个总结。
1)何谓COM?
COM全名为组件对象模型,其核心是将对象实现的细节封装起来,客户程序只能通过接口调用组件提供的方法,这是面向接口的编程,大大简化了面向对象中的编程负担,你不需要再去了解你使用的类是从多少父类层层嵌套过来的,你也不需要察看任何源代码。寥寥数语,不能讲清楚博大精深的COM本质,还是去看COM本质论吧。
2)何谓COM+?
COM+是什么?是微软提出的一种创建分布式应用程序的解决方法。分布式应用程序的特点是巨大,非常的复杂。但是任何分布式应用程序都需要解决一些共性问题,比如:安全、并发、网络传输的可靠性等。但是这些共性问题都是需要耗费极大的人力、物力、财力,而且最关键的是,绝大多数的项目开发队伍是不具备这种专业素质的。如何能够将项目开发人员的负担减少到最轻,使他们只需要考虑与业务相关的编码?很多大公司进行了这些探索,微软的解决方案就是COM+。
3)COM和COM+的关系?
我们可以编写包含业务逻辑的中间件(以COM的DLL形式),然后将它安装到COM+管理器中,进行简单的设置,就可将它作为分布式系统的服务器程序。
4)COM+的对象池
为了应付成千上万的互联网用户(通过WEB方式请求服务的客户),COM+提供了对象池。对象池的意义在于一个组件实例被创建之后,就可以保存到对象池中,如果需要,就从池中激活使用,这样就避免了重复创建的开销。对象池也可以设置容量大小,超过了对象池能够承受的容量,客户的请求就会被拒绝,这样避免了无限制的创建对象导致服务器崩溃。
5)COM+的JITA
JITA全称为即时激活。通常Intranet中的客户一旦连接上服务端,无论调用还是不调用方法都会一直保持连接,这样很耗费资源。JITA将在调用时创建对象,提供服务,调用完后立刻摧毁对象。但是客户是感觉不到的,客户程序仍然认为和服务器的连接存在,甚至可以缓存接口指针。
JITA和对象池也可以合作。但是对象池和JITA的使用者必须清楚内部的激活、钝化机制,并不是简单的配置一下COM+管理器就可以了。下文将创建一个测试程序,分析对象池和JITA的工作流程。
1)创建FBTEST项目,选择支持COM+1.0,取消属性化
2)在添加类向导中,添加COM+1.0组件TEST
3)选择支持IObjectControl,其余可以不选,因为我们只讨论IObjectControl接口。
IObjectControl接口简介:
该接口由你来实现,由com+调用,也就是客户代码不应该调用该接口的任何方法。
当对象被激活时,com+将调用Activate方法;
当对象被钝化时,com+将调用Deactivate方法;
对象可以控制自己是否应被放入对象池中,可以在CanBePooled方法中返回TRUE或者FALSE。
测试COM+是如何激活/钝化TEST对象的:
首先我们要创建一个客户程序TestClient,如何创建我这里就不介绍了,毕竟是太初级的东西。在组件实现类CTest类的构造函数等函数中添加如下代码:
CTEST()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行构造函数"<<endl;
}
HRESULT FinalConstruct()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行FinalConstruct"<<endl;
return S_OK;
}
void FinalRelease()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行FinalRelease"<<endl;
}
HRESULT CTEST::Activate()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行Activate"<<endl;
HRESULT hr = GetObjectContext(&m_spObjectContext);
if (SUCCEEDED(hr))
return S_OK;
return hr;
}
BOOL CTEST::CanBePooled()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行CanBePooled"<<endl;
return FALSE;
}
void CTEST::Deactivate()
{
ofstream file("c://test.txt",std::ios::app);
file<<"正在执行Deactivate"<<endl;
m_spObjectContext.Release();
}
传统的进程内调用com组件方式:
现在我们运行客户程序,创建并销毁组件,注意,这里我们还没有使用COM+管理TEST组件。结果如下:
正在执行构造函数
正在执行FinalConstruct
正在执行FinalRelease
表明IObjectControl接口中的方法还没有被调用。
COM+对象池调用方式:
我在WIN XP的组件服务管理器上创建服务器应用程序TEST,并将FBTEST组件加载进来,然后设置激活方式如下:
然后我们再运行客户程序。结果如下:
正在执行构造函数
正在执行FinalConstruct
正在执行Activate
正在执行Deactivate
正在执行CanBePooled
正在执行FinalRelease
可以看见IObjectControl接口的三个方法被com+依次调用,出人意料的是CanBePolled是在Deactivate方法之后调用的。如果CanBePooled函数返回S_OK,就不会执行FinalRelease函数。
COM+JITA调用方式:
如果我们取消对象池设置,只选择实时激活方式,我们观察到如下结果:
正在执行构造函数
正在执行FinalConstruct
正在执行FinalRelease
为什么COM+没有调用Activate方法?想想JITA机制是用于方法调用的,如果没有调用方法,当然使用JITA没有任何影响。现在我们给TEST加上调用方法F(void )的代码。再次调用之后,我们发现结果变了:
正在执行构造函数
正在执行FinalConstruct
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行FinalRelease
这里有一件奇怪的事情,在COM+1.5中,无论怎么样,方法调用后都会调用Deactivate方法,尽管我们在方法F最后加了如下代码
IContextState* pContextState;
::CoGetObjectContext(IID_IContextState,(void**)&pContextState);
pContextState->SetDeactivateOnReturn(FALSE);
pContextState->Release();
但是没有奏效,而且也不管COM+组件方法属性上是否选中了“此方法返回时自动停用此对象“选项。结果都是会调用Deactivate方法。我不知道COM+1.0是否如此,但是我已经不打算使用COM+1.0了。我们姑且认为JITA启用时一定会调用Deactivate方法。
对象池、JITA结合的调用方式
现在我们同时使用这两种方式,再来观察结果:
正在执行构造函数
正在执行FinalConstruct
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行CanBePooled
正在执行FinalRelease
这里多了调用CanBePooled,问是否要放入池中,如果返回TRUE,则对象不会被销毁,而是放入池中,FinalRelease方法就不会被执行,否则就执行FianlRelease方法销毁对象。
当同时时用了对象池和JITA之后,我们多次调用客户端,结果如下
正在执行构造函数
正在执行FinalConstruct
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行CanBePooled
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行CanBePooled
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行CanBePooled
正在执行Activate
正在执行方法F()
正在执行Deactivate
正在执行CanBePooled
构造函数和FinalConstruct函数自从第一次被调用之后,再也没有被调用过,如果我们很大的初始化的开销,放在这两个函数中只做一次,将是非常好的选择。
1)在创建COM+组件时----(这里的COM+组件,我指的是创建一个COM组件,该组件将安装在COM+管理器上作为分布式应用的中间件)我们应该实现IObjectControl接口,并且支持对象池(通过让CanBePooled返回TRUE)。
2)为了适应最特殊的情况,我们应该将组件的激活方式设置为同时支持对象池和JITA两种情况。
3)我们要将与特定客户相关的初始化动作放在Activate方法中,将清除动作放到Deactivate中。如果初始化的动作对于所有的客户调用一样,则可以放到构造函数中,这样对象从池中激活时就省去了初始化这些通用状态的步骤,提高了效率。
4)如果对象内部有指向其他组件接口的指针成员变量,该成员变量要么在Activate中创建,要么在GIT中注册,在Activate中获取。
5)所有上面的结论只是为了使初学者不易出错,一旦你发现你能够深入地了解对象池和JITA,你可以为了效率而定制你的代码和COM+配置,优点是获得了更高的效率,缺点是通用性不强。
6)对象池不会销毁对象,所以对象的状态(即成员变量)将会被保存,下次从池中激活时仍然有效,唯独接口指针成员变量由于切换了上下文而不能正确散集,所以必须采用4)中所述方法。
7)如果你在Activate方法中初始化,那么对象必须至少采用对象池和JITA中的一种激活方式,否则初始化不能正确执行。
分享到:
评论

相关推荐

    《COM+编程指南》源代码

    6. **对象池**:为了提高性能,COM+实现了对象池,它可以复用已创建的对象,减少对象的创建和销毁开销。 7. **生命周期管理**:COM+自动化管理组件的生命周期,包括实例化、激活、消亡等过程,使得开发者可以专注于...

    C# COM+编程指南(书籍与源码)

    6. **池化和并发**:了解COM+的线程池和对象池,以及如何配置这些池以优化性能和资源管理。 7. **安全性**:学习COM+提供的角色基的安全模型,以及如何在C#代码中实施权限管理和访问控制。 8. **设计模式**:书中...

    com+编程指南(pdf)

    COM(Component Object Model)是微软提出的一种组件对象模型,它是一种二进制标准,允许不同应用程序之间共享代码和数据。COM+是COM的扩展,它引入了更多的服务和概念,如事务处理、安全性、事件路由等,使得组件...

    Vue技术七大问题避坑指南+编程技术开发+编程问题+编程案例

    Vue技术七大问题避坑指南+编程技术开发+编程问题+编程案例Vue技术七大问题避坑指南+编程技术开发+编程问题+编程案例Vue技术七大问题避坑指南+编程技术开发+编程问题+编程案例Vue技术七大问题避坑指南+编程技术开发+...

    使用Python框架,绘制小熊动物图案+六一儿童节+编程学习+编程礼物

    使用Python框架,绘制小熊动物图案+六一儿童节+编程学习+编程礼物使用Python框架,绘制小熊动物图案+六一儿童节+编程学习+编程礼物使用Python框架,绘制小熊动物图案+六一儿童节+编程学习+编程礼物使用Python框架,...

    COM++编程指南.pdf

    **COM++** 是一种面向对象的编程框架,它结合了COM(Component Object Model)和C++的优势,提供了一种高效、灵活的方式来创建和使用组件。通过COM++,开发人员可以在多种语言之间共享代码,并实现跨平台的应用程序...

    编程技术+redis常用7大命令+技术开发+编程学习

    redis命令实践,编程技术+redis常用7大命令+技术开发+编程学习编程技术+redis常用7大命令+技术开发+编程学习编程技术+redis常用7大命令+技术开发+编程学习编程技术+redis常用7大命令+技术开发+编程学习编程技术+...

    网络工程师知识点大全+网络+编程

    网络工程师知识点大全+网络+编程; 网络工程师知识点大全+网络+编程; 网络工程师知识点大全+网络+编程; 网络工程师知识点大全+网络+编程; 网络工程师知识点大全+网络+编程; 网络工程师知识点大全+网络+编程; ...

    MATLAB GUI仿真案例+编程知识+技术开发+Matlab仿真编程

    MATLAB GUI仿真案例+编程知识+技术开发+Matlab仿真编程; MATLAB GUI仿真案例+编程知识+技术开发+Matlab仿真编程; MATLAB GUI仿真案例+编程知识+技术开发+Matlab仿真编程; MATLAB GUI仿真案例+编程知识+技术开发+...

    C# COM+ 编程指南

    7. **配置和管理**:使用COM+ Administrator工具,可以对COM+应用程序、组件和服务进行配置和管理,包括设置安全策略、事务属性、池大小等。 8. **错误处理和调试**:在C#中调用COM+组件时,需要处理可能抛出的异常...

    Matlab课程体系+编程知识+技术开发

    Matlab课程体系+编程知识+技术开发; Matlab课程体系+编程知识+技术开发; Matlab课程体系+编程知识+技术开发; Matlab课程体系+编程知识+技术开发; Matlab课程体系+编程知识+技术开发; Matlab课程体系+编程知识+...

    Json知识简介+编程知识+技术介绍

    Json知识简介+编程知识+技术介绍;Json知识简介+编程知识+技术介绍;Json知识简介+编程知识+技术介绍;Json知识简介+编程知识+技术介绍;Json知识简介+编程知识+技术介绍;Json知识简介+编程知识+技术介绍;Json知识...

    Vue开发:技术与经验深度解析+编程知识+技术开发+Vue编程技术

    Vue开发:技术与经验深度解析+编程知识+技术开发+Vue编程技术; Vue开发:技术与经验深度解析+编程知识+技术开发+Vue编程技术; Vue开发:技术与经验深度解析+编程知识+技术开发+Vue编程技术; Vue开发:技术与经验...

    Swift课程体系设计+编程知识+技术开发

    Swift课程体系设计+编程知识+技术开发; Swift课程体系设计+编程知识+技术开发; Swift课程体系设计+编程知识+技术开发; Swift课程体系设计+编程知识+技术开发; Swift课程体系设计+编程知识+技术开发; Swift课程...

    MySQL查询语句汇总+编程知识+开发技术

    MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询...

    如何设计一套Scratch编程课程体系+编程知识+技术开发

    如何设计一套Scratch编程课程体系+编程知识+技术开发; 如何设计一套Scratch编程课程体系+编程知识+技术开发; 如何设计一套Scratch编程课程体系+编程知识+技术开发; 如何设计一套Scratch编程课程体系+编程知识+...

    c&c++编程实战:图书管理系统.zip

    c&c++编程实战:图书管理系统.zip c&c++编程实战:图书管理系统.zip c&c++编程实战:图书管理系统.zip c&c++编程实战:图书管理系统.zip c&c++编程实战:图书管理系统.zip c&c++编程实战:图书管理系统.zip c&c++...

Global site tag (gtag.js) - Google Analytics