在注册(RegAsm)我的C#COM可见类之后,我发现CoCreateInstance(__uuidof(myclass))
仅在第一次花费大量时间,同一客户端进程中的后续尝试立即得到解决。知道为什么需要时间吗?
NGen对我来说不是一个选择。
我的COM服务器在C#中,客户端在MFC / ATL
CComPtr<namespace::Imyclass> obj;
hrx = obj.CoCreateInstance(__uuidof(namespace::myclass));
答案 0 :(得分:1)
第一次调用CoCreateInstance
必须加载进程并初始化.NET运行时。然后,您的DLL必须被加载,“验证”,并编译成机器代码(虽然及时帮助加速启动)。 .NET运行时还必须解析程序集的元数据,然后动态生成并编译“COM可调用包装器”(http://msdn.microsoft.com/en-us/library/f07c8z1c.aspx),它们是在非托管COM世界和托管.NET运行时之间桥接的代理。 。您的代码可能使用的任何其他库也需要加载,验证并可能编译为机器代码(如果不是NGEN)。
这本质上是一个昂贵的过程。你提到的延误并非闻所未闻。
我不相信你可以做很多事情来加快速度。我建议你考虑是否可以通过在启动后不久创建一个对象来在程序的生命周期中尽早获得命中。它不会让它变得更快,但它可能会显着改善用户体验。如果您的程序无法容忍延迟,那么您不应该使用.NET来编写COM对象(更具体地说,您根本不应该在您的进程中使用.NET。这不是使用COM的问题;它是一个加载.NET的问题)
顺便说一句,这就是为什么在.NET中编写shell扩展的原因之一......“非常气馁”。请参阅最近关于此主题的帖子,该帖子也涉及.NET的启动性能:http://blogs.msdn.com/b/oldnewthing/archive/2013/02/22/10396079.aspx
(这就是为什么我之前问过你运行的是什么类型的客户端。已经运行.NET托管代码的客户端依赖于.NET运行时并且不会受到这些延迟的影响)
答案 1 :(得分:0)
第一次调用CoCreateInstance
可能需要咨询注册表和文件系统,加载适当的代码,允许它初始化,最后调用工厂来创建你要求的实例(如果可以找到它。
第二个电话会议从以前的步骤中获益匪浅。如果第一次调用成功,则代码已经加载并初始化,而它所要做的就是第二次调用工厂。
答案 2 :(得分:0)
如果此延迟仅适用于首次加载(计算机启动后),则这是由加载所有库引起的。启动后的第一次延迟(或长时间不使用.NET)总是很慢。 (见Micelli回答)
每次加载也会导致延迟。今天我发现互联网连接也会导致延迟。
测量值:
*非标准网关:允许每台计算机的TCP端口和连接不同(WinXP和Win7不同)。
在Windows 7(x64)和WinXP上测试。我对它进行了测试,因为它是来自客户的抱怨,并将延迟定位于 CoCreateInstance 加载的库位于c#中并且已签名(带有snk的签名程序集以及用于签署可执行文件的标准证书)