实现客户端
      当一个基于CLR 组件服务类被编译和部署,你就需要在客户端调用它。长远来看,组件服务类没什么特别之处;事实是使用COM+ 运行时服务是不相关的。 这个代码展示了简单类早期的定义MyTxCfgClass:
using ESExample;
public class Client
{
 public static void Main(string[] args)
 {
    MyTxCfgClass tcc = new MyTxCfgClass();
    ... // use object as desired
 }
}
      当然,与所有的CLR代码,客户端必须引用组件服务类程序集。
csc /r:ESExample.dll Client.cs
细微的复杂性
      这里你会看到,服务类通过 .NET CLR实现COM+是相当的容易。 System.EnterpriseServices 命名空间里的类提供了可以使用COM+运行时服务的API。运行时服务本身没什么改变;他们工作的方式还是 COM+开发者熟知的。已经说了, 集成COM+和CLR 没有涉及到如此细微的复杂性。 有几个问题是使得使用CLR语言写 COM+ 代码比我刚才提到的复杂的多。 有些问题会产生,因为CLR毕竟不是 COM, 因为它可以做COM做不到的事情。这些问题是不能解决的; 你只要知道如何CLR的特性如静态方法和垃圾回收器 如何影响COM+ 编程。
      再学习这些问题前,你必须知道CLR 的类和 and COM+ 上下文环境的关系。 首先,调用继承自ServicedComponent的类的实例都会被COM+ 上下文环境边界侦听。这些对象称为上下文环境边界。调用没继承自ServicedComponent的类的实例就不会被上下文环境边界侦听。 这些对象称为context-agile。CLR对象默认就是context-agile。 当你继承自ServicedComponent它们会变成context-bound 。(这个与 .NET remoting 上下文环境没有关系,我下面会讲到。) 图 9说明的这个架构
 9 上下文环境对象

非常有趣的是CLR 对象可以实现类似COM 对象和COM+ 上下文环境交互这样的行为。通过 COM,调用对象通常默认都会被侦听; 所有的对象都是context-bound。COM 对象是context-agile 只有当它聚集了freethreaded marshaler (FTM)且不是第一个在COM+ 上下文环境里 被创建的对象(因为它不是可识别的对象), 这样情况下,调用不会被侦听。 新方法确保调用真的需要的时候被预处理和迟处理的好处是减少了侦听负荷。 特别地,如果组件服务类的实例返回了一个非组件服务类的实例 (例如一个 ADO.NET DataSet 对象),这个调用不会被侦听。 并且DataSet对象不需要做任何事情,它就是照常工作。

      第二个你应该知道的事情是, 除了减少真正需要的交叉上下文侦听外, CLR/COM+集成尽可能地避免了托管类型和自有类型间的转换。 来自托管的CLR 代码到COM的调用是比较昂贵的。重要的部分就是类型的前后转换—大部分在CLR strings和COM BSTRs之间。 请求穿过COM+环境边界需要 调用一些固有的代码, 组件已经相当聪明可以避免同样来自CLR且处在同一进程里的调用者和被调用者之间的类型转换。 或许有一天所有的COM+ 运行时服务都会用CLR语言重新实现,调转就不成问题了。 那时不管如何,这个优化都会使得COM+ 侦听更加快速。
静态方法和属性
      现在你知道了CLR代码如何关联上下文环境, 思考这个问题:如果一个基于CLR 组件服务类 包括静态方法和属性访问器, 它将在什么上下文里执行呢?答案是调用者。 这个看起来不是很直观, 但是它确实很有意义当你想静态成员不是对象定义且不许要在对象驻留的上下文里访问。例如,组件服务类在图 10有个静态方法,2, 和静态属性,4。这个代码会在调用者的上下文里执行。 调用实例的方法1, 或者属性3,通常在对象的上下文里执行。
     这时你或许想知道当你在属性里保存了一个对象的静态引用且你想在另外一个上下问里引用会发生什么事情。基于COM的COM+编程里, 在被成为静态属性的全局变量里保存了一个原始的对象引用, 会导致严重的错误因为你不可以把对象不加包装地从原来的上下文里带走。使用基于CLR COM+ 代码, 这个就不是一个问题。 CLR 使用相当瘦的代理包装了每个组件服务类的实例子这样其它上下问的对象就不需要保留对象的直接引用。如果代码在一个保留基于CLR 组件服务类引用在静态属性的的上下文执行。它实际保留的是一个引用。如果另一个上下文里的代码要通过静态属性访问它, 特定的代理就发现变化而且封装它自己保留的引用这样侦听就触发了。这个是有个优美的解决方案,本质上你可以任何地方保存基于CLR服务类的实例并且都会正确触发。
     
管理珍贵的资源
     我现在开始另外一个管理对象引用的话题',另外一个问题你必须注意CLR靠垃圾收集器回收内存。 这是个重要的事情因为它要自动帮助避免内存泄露并且释放闲置的内存。非常不幸的是, 垃圾收集器使得内存管理变的容易,但是他同样带来了其他问题,比如管理COM+设计的对象变的困难。因此高效地管理资源是建立可伸缩的系统的关键,这正是COM+ 的设计目标,你需要知道如果合理地释放基于CLR的资源。
     考虑 CLR类使用到了SqlConnection 对象连接数据库, 如下所示:
public void UseADatabase(void)
{
 System.Data.SqlClient.SqlConnection =
      new System.Data.SqlClient.SqlConnection(…);
    …// use connection to execute statements
}
在UseADatabase方法的结束部分, SqlConnection 对象被释放。 SqlConnection对象封装了处理数据库的连接并且为了效率考虑被ADO.NET底层机制池化(Beta 1 使用COM+ 对象池; Beta 2, 使用了类似COM+ 对象池的机制)。 问题是 SqlConnection对象管理的连接何时归还到对象池? 不等垃圾收集器进入,就意识到SqlConnection 对象不在被使用,就调用终结器。finalizer 把连接归还给对象池, 然后SqlConnection对象的内存就被回收。
      问题是数据库连接资源是非常珍贵的资源,你不能让他们无约束地飘荡在内存里,直到垃圾收集器来回收。 需要一些方法来回收这样的资源。一种方式就是强制垃圾收集器执行回收工作,如下所示:
public void UseADatabase(void)
{
 System.Data.SqlClient.SqlConnection conn =
      new System.Data.SqlClient。SqlConnection(…);
 … // use connection to execute statements
 conn = null;
 System.GC.Collect();   
}
然而,这个方法相当的笨拙且有很多潜在问题。
     更好的方法是调用SqlConnection 对象实现的接口的 IDisposable.Dispose方法。 IDisposable 接口在System命名空间,它规范拥有昂贵的要清理的资源的对象通过客户端定义操作释放资源代理垃圾收集器回收的行为。SqlConnection实现了Dispose,快速归还对象给对象池 (事实上和调用finalizer的作用一样)。
      下面代码是新版本的UseADatabase方法,它显示的清除了SqlConnection。
public void UseADatabase(void)
{
 System.Data.SqlClient.SqlConnection conn =
      new System.Data.SqlClient.SqlConnection(…);
 try
 {
    … // use connection to execute statements
 }
 finally
 {
    Conn.Dispose();
 }
}
注意到Dispose出现在finally块里确保它可以执行,不管是否抛出异常。
      那这个和COM+与服务类有什么关系呢? 首先,你的服务类很可能使用数据库连接和其它昂贵的资源, 所以如果你希望系统净化,你就应该知道如果合理地释放资源。 第二是, 所有基于CLR 服务类 实现了IDisposable.Dispose方法, 因为基类,ServicedComponent。你应该知道当客户端调用Dispose时发生了什么。默认实现的行为取决于你的组件服务类 使用了什么运行时服务。如果你没使用对象池激活, Dispose就会立即调用 finalizer (如果已经被垃圾收集器回收,就不会再调用)。如果你的组件服务类 使用了对象池而不是JIT 激活, Dispose调用Deactivate去通知对象已经离开它当前的上下文。然后它就调用 CanBePooled 去询问对象是否重用或销毁。 如果CanBePooled返回true, 对象会返回到对象池里。 返回false, 对象的finalizer就会调用 (如果已经被垃圾收集器回收,就不会再调用)。 非常重要是客户端为池化的对象调用方法Dispose,如下所示。
public void UseAPooledObject(void)
{
 MyPooledCfgClass pcc = new MyPooledCfgClass();
 try
 {
    …// use pooled object to do something
 }
 finally
 {
    Pcc.Dispose();
 }
}
      如果不调用Dispose,对象 (如描述的数据库连接), 只有等到垃圾收集器回收资源。 最后, 如果你自己实现组件服务类的Dispose方法, 你必须调用基类的实现去实现这些描述的行为。
[ Synchronization(SynchronizedOption.Required) ]
public class MyCfgClass : ServicedComponent
{
 public new void Dispose()
 {
    … // do whatever
    Base.Dispose(); // call base to clean up
 }
}
    你或许想知道 JIT 激活和反激活一个对象在方法的结束。 那解决了资源的管理问题了吗?答案是否。 反激活使得对象在结束调用前释放自己成员所有的资源, 同样包括想使用相同资源的的每个方法调用。你可以通过不保存任何资源的方式达到这个目的。如果你没有选择 JIT 激活 和反激活在每次方法调用的结尾, 知道客户端调用Dispose实际上是强制你的对象重激活到饭激活并且重新终结一次。通常情况下, 到CLR的转换不会改变的JIT 激活规则。 应该避免使用它除非运行时服务需要它 (比如声明的服务) 因为它不会更高效, 且 比你自己管理昂贵的资源效率低。
展望
      ServicedComponent 类继承自 System。ContextBoundObject, 它又继承自System。MarshalByRefObject, 这个基类可以使对象可以通过.NET remoting机制 被访问到。在Remoting顶层 上进行CLR/COM+集成有两个好处。首先你能通过Remoting层使用SOAP访问COM+ 运行时服务的远程对象。但是你不能够使用SOAP传递事务到另外的进程 (非你所愿, 但道理如此)。 第二点,打开了新版的新的基于CLR Remoting上下文架构实现的COM+ 运行时服务的方式 这是现在的COM+所没有用到的。 将来一定会够发生。 真要这样,服务就可以与SOAP或者其他的传输无逢集成,并且上下文就可以真的可以扩展了。那时, 已经正确跨出一大步的CLR 就会使得COM+编程变的更加容易。
相关文章:
Windows XP: Make Your Components More Robust with COM+ 1.5 Innovations
House of COM: Migrating Native Code to the.NET CLR
the "samples"technologies"component服务 subdirectory of the.NET Framework SDK
事务al COM+: Building 可伸缩的应用系统 by Tim Ewald (Addison-Wesley, 2001)
作者Tim Ewald: DevelopMento的首席科学家, 最近出版的 事务性COM+: 创建可伸缩的应用系统 (Addison-Wesley 2001)的作者
翻译Frank Xu Lei:程序员,技术博客http://www.cnblogs.com/frank_xl/
来自10 2001 MSDN杂志



 本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/321005,如需转载请自行联系原作者


经典技术文章翻译(1):COM+集成:.NET Enterprise Services 如何帮你建立分布式应用(2)相关推荐

  1. 谈技术文章翻译的信雅达-上

    谈技术文章翻译的信雅达-上 Horin|贺勤         Email: horin153@msn.com         Blog: http://blog.csdn.net/horin153/ ...

  2. 谈技术文章翻译的信雅达-下

    谈技术文章翻译的信雅达-下 Horin|贺勤         Email: horin153@msn.com         Blog: http://blog.csdn.net/horin153/ ...

  3. [经典文章翻译]A Crash Course on the Depths of Win32 Structured Exception Handling

    转自:[已完工][经典文章翻译]A Crash Course on the Depths of Win32 Structured Exception Handling 原文题目: <<A ...

  4. AI在线文章翻译工具多翻译api接口对接集成工具

    AI在线文章翻译具有多语言的翻译,互译和回译选项,只需要简单的操作就可以对我们的批量文章进行在线翻译处理,生成我们需要的文种,对于翻译质量的把控,AI在线文章翻译工具对接谷歌等大厂的翻译接口,也具有自 ...

  5. 写技术文章也挺好的,虽然没有多少人看

    微信改版信息流以后,正式进入了"拼标题"时代,如果没有一个吸引眼球.摄人心魄,不点进来心里就痒痒的标题,那阅读量肯定是嗖嗖地下降. 偏偏我又不擅长此道,绞尽脑汁想了个自以为是10w ...

  6. 【合集】Jerry Wang 2018~2021 四年期间的 SAP 技术文章合集

    这是 Jerry 2021 年的第 75 篇文章,也是汪子熙公众号总共第 352 篇原创文章. 大家好,我是 Jerry Wang,从 2007 年起在 SAP 成都研究院工作至今.我是一名全栈开发工 ...

  7. 2017上半年技术文章集合—184篇文章分类汇总

    声明 | 作者 :于亚豪 | 原创 | 终端研发部 前言: 2017年已经过大半,公众号里技术文章整理和归类了一下,方便给大家查找和阅读.这也是目前 发文的一个统计. View篇: 高级UI特效之酷炫 ...

  8. A Crash Course on the Depths of Win32 Structured Exception Handling(文章翻译)

    [经典文章翻译]A Crash Course on the Depths of Win32 Structured Exception Handling 原文题目: <<A Crash Co ...

  9. SAP成都研究院2018年总共87篇技术文章合集

    2018年很快就要结束了.Jerry在2017年年底准备开始写这个公众号时,给自己定的目标是:2018年至少保证每周发布一篇高质量的文章.如今2018年就快过去了,高质量与否需要大家来反馈,至少从量上 ...

最新文章

  1. 通信系统未编码、卷积码与格雷码的仿真性能比较
  2. 【Qt】QtCreator中关于Style Plugin Example没有效果的修改方法
  3. redis命令_Redis 命令执行过程(下)
  4. mysql 怎么导入函数_mysql导入导出包括函数或者存储过程_MySQL
  5. [转] Deep Learning(深度学习)学习笔记整理系列
  6. 收集 48 个 JavaScript 代码片段,仅需 30 秒就可理解(值得收藏)
  7. WPAD原理介绍暨故障排查:ISA2006系列之三
  8. html 响应式布局 九宫格,两种方法实现响应式九宫格布局
  9. 95-190-540-源码-window-清除器(Evictors)-简介
  10. Java反射异常处理之InvocationTargetException
  11. html做一个年份月份天数选择器,jquery编写日期选择器
  12. 云计算 third day
  13. excel有多行不同内容需要向下填充
  14. 全国计算机等级考试二级Web程序设计考试大纲(2018年版)
  15. ERP能力计划与排产
  16. 开发者都能读懂的云原生指南 —— 新程序员003
  17. Doctype作用?标准模式与兼容模式各有什么区别?
  18. opengl 着色器
  19. resolution will not be reattempted until the update interval of XXX has elapsed or updates are force
  20. 什么样的自学Java网站才适合学习者?

热门文章

  1. UA OPTI512R 傅立叶光学导论3 用复变函数表示物理量
  2. UA PHYS515A 电磁理论V 电磁波与辐射8 单个粒子的辐射 匀速运动与匀加速运动的情况
  3. javascript闭包简单实例
  4. 详细图解JDK+Tomcat Web开发环境配置和HelloWorld程序
  5. Java 学习笔记 反射与迭代器
  6. 聊聊、Java SPI
  7. 【Java】详解菜单组件
  8. hdu 2680 Choose the best route
  9. 递归实现数字排列组合
  10. oracle spatial 数据导入_【转】 Oracle Spatial 基本操作