RSS 2.0 Feed
ServicedComponent(企业服务)
摘要:企业服务优化原则中有下面一条原则,最近我优化一个企业服务时,对此有了特别深刻的体验,特整理本篇博客: 使用 COM 可封送的参数如果企业服务组件的方法接受调用方传递数据时所用的参数,强烈建议您尽量使用 COM 和 .NET 之间易于封送的类型,例如: ? Boolean ? Byte、SByte ? Char ? DateTime ? Decimal ? Single、Double ? Guid ? Int16、UInt16、Int32、UInt32、Int64、UInt64 ? IntPtr、UIntPtr ? String 如果仅使用这些类型,且要避免传递其他复杂的类型(例如 structures 或 arrays),.NET 序列化程序可以优化调用处理堆栈,并将调用直接序列化到线缆上(对于 RPC)或到虚拟线缆上(对于 LRPC)。这样,调用的执行速度更快。不过,如果您的方法要求复杂的类型,代码将使用通常的 DCOM 调用堆栈调用,这将产生额外的处理。 以上文字来自: .NET 企业服务性能  我最近优化的这个企业服务是CSDN新积分制论坛帖子列表企业服务缓存。 这个帖子列表缓存工作机制如下: 1、启动一个 ActivationOption.Server 的企业服务(ServicedComponent),这个企业服务是工作在一个独立的服务程序进程。 2、这个企业服务中,通过单件模式启用了一个缓存,缓存了CSDN每个大小论坛的帖子列表。 3、当WEB应用启动时候,把每个论坛,每种帖子列表的帖子都从数据库中获得,然后记录到缓存中。方便以后使用。 4、在优化前,这个版本的新积分制论坛并不是所有CSDN的论坛,有100左右的大小论坛,每个大小论坛又有6种帖子列表,每个帖子列表最多显示满足条件的500条记录。这样,初始化数据大致就需要 100*6*500 大致20万左右的数据需要初始化到帖子列表企业服务缓存。 下面是我做测试的三种情况: 1、优化前我代码逻辑:每一个论坛做一次初始化操作,也就是100个论坛调用企业服务的一个方法100次。 这样的代码逻辑,本地测试环境,完成初始化大致需要130秒左右。 2、我把这个初始化的代码,即从数据库获得并写到缓存的代码搬到企业服务内部执行,外部只需要传递一个简单的论坛编号即可。这样优化后,这个初始化过程大致需要40秒。 3、另外一种方法,我把100个论坛所有帖子列表的数据库都在企业服务外部计算好,然后一次性提交给企业服务,即企业服务这个初始化方法只调用一次,完成这个初始化大致需要190秒左右。 对比我做的上面三个测试情况,我们可以看到,业务逻辑没有发生任何变化,变化的只是企业服务接口参数发生变化了,把一些工作从企业服务外搬到了企业服务内部执行。三种情况对企业服务来说,差别就在于企业服务的参数发生变化了。 上面情况2的企业服务参数最简单,用的是Guid 类型的参数。 情况1和情况3用的是自定义的可序列化的类。 情况1企业服务调用了100次,情况3企业服务只调用了1次。 结论: 1、企业服务的参数要尽量使用 COM 和 .NET 之间易于封送的类型,而不是自己定义的实体和传递其他复杂的类型。 2、企业服务使用自己封装的实体或者复杂的类型,带来的性能损耗,比多次调用企业带来的损耗更厉害(对比情况1和情况3) 参考资料: .NET 企业服务性能...[阅读全文]

posted @ | Feedback (4) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 ServicedComponent(企业服务) ]

摘要:我们要在这篇文章中将实现的功能: 如上图荧光笔画的地方所示: 我们需要通过编写服务程序的安装程序,把企业服务上面 Run application as NT Service 选择框的进行选中操作。   阅读本文基础: 如果你对企业服务不是很了解,可以阅读我之前写的一系列跟企业服务有关的博客。我书写的跟企业服务有关的系列文章可以访问以下链接。 http://blog.joycode.com/ghj/category/1320.aspx 如果你对编程控制企业服务根本不了解,需要首先阅读我之前写的这篇博客: 编程控制企业服务的行为 本文是在上述文章基础上的加深。   正文 编程控制企业服务的行为 这篇博客中我讲到,我们可以通过遍历 COMAdminCatalogCollection 来寻找到我们需要操作企业服务的某个属性,然后更新这个属性。这种做法适用于大多数编程操作企业服务属性。但是我们上面这个需求就无法用这种方式来作了。 我们遍历 COMAdminCatalogCollection 可以更新的属性时候,我们在微软提供的可操作属性列表(如下链接可以看到)中并没有找到可以设置 Run application as NT Service 的选项。 http://msdn2.microsoft.com/en-us/library/ms686107.aspx 只能看到一个可能跟这个需求有关的属性: ServiceName The service name corresponding to the application configured to run as an NT service. If this value is NULL, the application is not configured to run as an NT service. Otherwise, the configuration information for the service can be found by using the service name. Access:    ReadOnly Type:        String Default:    "" Platform Requirements:   Windows XP, Windows Server 2003 这个属性是只读的,我们又没法设置。   如何解决这个问题呢? 很简单,这个需求不是通过属性来指定的,而是通过 COMAdminCatalog 类的 CreateServiceForApplication 方法。 简单来说,我们就是要安装代码中有以下代码:......[阅读全文]

posted @ | Feedback (4) | Filed Under [ .net 编程心得 技术随笔 ServicedComponent(企业服务) ]

摘要:我们如果需要编程控制企业服务的行为,则可以利用 COMAdminCatalog 来进行操作。使用 COMAdminCatalog  之前,需要增加一个 Com 引用 COM +1.0 Admin Type Library ,如下图: 下面就简单的实现一个功能,遍历每个COM+ 应用,并显示出他们的一些信息。同时,如果找到你指定的 COM+ 应用,则设置它一直运行(Leave running when idle)。 using COMAdmin; COMAdminCatalog ca = new COMAdminCatalogClass(); COMAdminCatalogCollection cacc = (COMAdminCatalogCollection)ca.GetCollection("Applications"); cacc.Populate(); foreach (COMAdminCatalogObject cac in cacc) { Console.WriteLine("**************"); Console.WriteLine(cac.Name); Console.WriteLine(cac.Key); Console.WriteLine(cac.Valid); string[] nameArr = new string[] { "Identity", "ID", ......[阅读全文]

posted @ | Feedback (6) | Filed Under [ ServicedComponent(企业服务) ]

摘要: 企业服务组件类的接口被定义在另外一个项目中,变更接口时候,导致错误:Unable to cast COM object of type 'System.__ComObject' to interface type 'I***' 的解决 方案 最近在完善兴趣小组的开发,企业服务这里,由于遵循谋个接口,而这个接口,会按照 需求,时不时发生变化。 但是一旦发生修改。经常会报类似如下的错误信息: 这个修改后,在 Component Services 中删除这个企业服务,在GAC中删除这个企业服 务组件以及这个组件所引用的组件,之后,重起电脑,你会发现,下述错误仍然存在。 An exception of type 'System.InvalidCastException' occurred in mscorlib.dll but ......[阅读全文]

posted @ | Feedback (7) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 VS2005相关 ServicedComponent(企业服务) ]

摘要:Com+ 类的部分代码: namespace TransactUserManage{?[Transaction(TransactionOption.Required)]?public class?TransactUserClass : ServicedComponent?{ ??public TransactUserClass()??{??} ??private string? strDeployName = null;??public string DeployName??{???get???{????return strDeployName;???}???set???{????strDeployName = value;???}??} ??private Hashtable objDataBaseConnStrArr = null ;??public Hashtable DataBaseConnStrArr??{???get???{????return objDataBaseConnStrArr;???}???set???{????objDataBaseConnStrArr = value;???}??} ??private string strCurrUserDataBaseConn = null;??public string CurrUserDataBaseConn??{???get???{????return strCurrUserDataBaseConn;???}???set???{????strCurrUserDataBaseConn = value;???}??}....? 其他代码。 ??public bool ModifyPenName(int iUserID,string strPenName)??{???if (!ContextUtil.IsInTransaction)????throw new Exception("ActivationUser 不支持事务处理!!");???string WhichSolution = strDeployName;????string strUserConn = strCurrUserDataBaseConn;????string strCSDNExpertConn = objDataBaseConnStrArr["CSDN_BBS_ConnStr"].ToString();????string strCSDNLtConn = objDataBaseConnStrArr["CSDN_Main_ConnStr"].ToString(); .... 其他代码} } } } 调用部分 ????TransactUserManage.TransactUserClass obj = new TransactUserClass();????obj.DeployName = ConfigInfoClass.DeployName;????obj.CurrUserDataBaseConn = ConfigInfoClass.CurrUserDataBaseConn;????obj.DataBaseConnStrArr = ConfigInfoClass.DataBaseConnStrCache;????bool result = obj.ModifyPenName(iUserID,strPenName); 这里我确认? ConfigInfoClass.DeployName?? ConfigInfoClass.CurrUserDataBaseConn?? ConfigInfoClass.DataBaseConnStrCache 都是正确的值。 但是进入到??? string strUserConn = strCurrUserDataBaseConn; 这里后, 单步调试 strCurrUserDataBaseConn 的值竟然是 null , 我确定 obj.CurrUserDataBaseConn = ConfigInfoClass.CurrUserDataBaseConn; 这里的 ConfigInfoClass.CurrUserDataBaseConn 是有值的呀。 ?...[阅读全文]

posted @ | Feedback (1) | Filed Under [ .net 编程心得 ServicedComponent(企业服务) ]

摘要:分布式应用如果用 Com+ 来开发的话,一个好处就是,你不用修改任何代码,只需要修改Com+的部署,既可以实现分布式。 下面是就是部署分布式Com+需要注意的一些东西和步骤: 部署要求:有A、B、C 三台机子。A机子是实际 Com+ 应用运行的机子。B、C机子调用A机子的Com+应用。 首先:在A机子部署Com+应用。如果这个应用是基于.net 开发的,只需要简单的执行下面两步:(TopicManage.dll 为假设要部署的Com+应用) gacutil -i TopicManage.dll? (部署到GAC,有些简单的Com+不需要部署到GAC中,后面一个Blog会具体谈到这个问题)RegSvcs TopicManage.dll 在确保本地部署Com+成功后。要进入 Component Services ,去修改已经部署的 Com+ 应用的默认设置。 在 Com+ 应用的属性中,首先需要在它的 Activation 属性中修改 Activation type 为 Server application(Run application as NT Service 的选项无所谓选不选,具体自己决定) 如下图: ? 如果只修改这一项,并保存,这时候启动这个 Com+? Application 会报下面错误: ---------------------------Catalog Error---------------------------You do not have permission to perform the requested action.? If security is enabled on the System Application of the target computer? make sure you are included in the appropriate roles.---------------------------OK?? --------------------------- 你需要修改这个 Com+ Application 的安全设置,在 Security 属性的 Authorization 中,确认 Enforce access checks for this application 这个选项没有被打勾。然后保存设置。启动这个Com+ 应用。这样A 机器的设置就完成了。 如下图: ? 下面我们需要到 B、C 机子安装 对 A 机器Com+ 的引用。 Com+ 应用可以方便的导出为一个安装文件。然后在其他机子上执行这个安装文件,实现其他机子的部署。 选择 A 机器的Com+? 应用,执行导出命令,在导出设置的时候,注意选择 Application proxy - Install on other......[阅读全文]

posted @ | Feedback (21) | Filed Under [ .net 编程心得 ServicedComponent(企业服务) ]

摘要: 企业服务组件类的接口被定义在另外一个项目中可能会出现的一种错误 最近在作的一个项目中,一个企业服务组件要遵循一个接口,类似如下: public class EnterpriseUserDataManager : ServicedComponent,ICommunityUserDataManager 我对 ICommunityUserDataManager 接口的定义在另外一个项目中。 这个接口有好几个函数,如下: public interface ICommunityUserDataManager { CommunityUser GetCommunityUser(string userName); void InsertCommunityUser(CommunityUser user); ......[阅读全文]

posted @ | Feedback (7) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 VS2005相关 ServicedComponent(企业服务) ]

摘要:使用自定义的类,作为函数的参数,可以解决传递参数过多的问题。在Com+ 中使用自定义的类来传递参数,需要注意以下几点: 编码需要注意的:你的自定义的类必须是可以序列化的,当然也可以继承自:? ServicedComponent 类。因为 从 servicedcomponent 继承 就直接有序列化标志了。 比如下面的代码就是正确的: ??? using System;??? namespace ComPlusLib??? {??????? public class WriteFileTest:System.EnterpriseServices.ServicedComponent??????? {??????????? public string SayHello(String s)??????????? {??????????????? System.IO.FileStream fs=new System.IO.FileStream("c:\\t.txt",System.IO.FileMode.Append,System.IO.FileAccess.Write);??????????????? System.IO.StreamWriter sw=new System.IO.StreamWriter(fs);??????????????? sw.WriteLine(s);??????????????? sw.Close();??????????????? fs.Close();??????????????? return System.Diagnostics.Process.GetCurrentProcess().ProcessName + s ;??????????? } ??????????? public string TestObject(Fac1 f)??????????? {??????????????? return f.FullName;??????????? }??????? } ??????? ??????? public class Fac1:System.EnterpriseServices.ServicedComponent??????? {??????????? public string ShowMyProcess()??????????? {??????????????? return System.Diagnostics.Process.GetCurrentProcess().ProcessName;??????????? } ??????????? public string FullName;??????? }??? } 部署需要注意的:在部署这个Com+ 的时候,注意,一定要把编译后的Dll也部署到GAC中。如果你没把这个Dll 部署到GAC,你会获得以下错误信息: Insufficient state to deserialize the object. More information is needed. 满足以上两个条件,你就可以在Com+ 中使用自定义的类作为函数的参数了。 在我的一个程序中,就是没有注意第一点,编写的一个Com+ 没有错误。但是其实他的执行不是走得Com+。 而是直接调用GAC中的函数了。一直到作分布式部署的时候,才发现程序的问题。...[阅读全文]

posted @ | Feedback (9) | Filed Under [ .net 编程心得 技术随笔 ServicedComponent(企业服务) ]

摘要:今天在写一个企业服务组件,是在一个ClassLibrary项目基础上修改的.这个企业服务中包含很复杂的业务逻辑,其中用到了Singleton 模式来确保只有一个缓存。相关技术参看:http://sajadi.co.uk/dflat/archives/2005/11/creating_a_cach.html 编译时候没有任何问题,然后就是部署,结果部署的时候报下面错误: 出现下列安装错误:1: 在程序集中找到无效的 ServicedComponent 派生类。(类必须是公共的、具体的、有公共的默认构造函数并满足所有其他 ComVisibility 要求) 这个错误信息让我对是否可以在企业服务中使用单键模式产生怀疑。网上也有不少对企业服务使用单键模式的讨论。观点各不相同,结果一下午就迷失在这里了。http://www.pcreview.co.uk/forums/thread-1382837.phphttp://www.pcreview.co.uk/forums/thread-1382837-2.php 一直到快下班,才发现,根本不是上述使用单键模式的问题,而是ClassLibrary项目的AssemblyInfo.cs文件,默认设置是 [assembly: ComVisible(false)] 如果你要做EnterpriseServices,则需要把这个修改为true ,汗颜,最基本的地方给忘掉了。 在AssemblyInfo.cs文件ComVisible上有明确的提示,自己竟然没留意,提示如下: // Setting ComVisible to false makes the types in this assembly not visible // to COM components.? If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type.[assembly: ComVisible(true)]...[阅读全文]

posted @ | Feedback (6) | Filed Under [ .net 编程心得 技术随笔 VS2005相关 ServicedComponent(企业服务) ]

摘要: 我写的一个项目,其中用到COM+(企业服务),今天早上的时候,突然发现项目编译不过去了。报错误: “Error code 80040154 - Class not registered” 细查下去,发现Com+的部署出了问题。 当我打开“Component Services”想看个究竟的时候,发现无法打开了,报错误如下图: “An error occurred while processing the last operation. Error code 80040154 - Class not registered The event log may contain additional troubleshooting information” ......[阅读全文]

posted @ | Feedback (7) | Filed Under [ .net 编程心得 技术随笔 ServicedComponent(企业服务) ]