我有一个托管组件的.NET 4.0 Windows服务。我们的项目主管说,在调用某些组件的方法时,性能很慢。他怀疑它可能是一个STA组件会导致性能损失。
为了测试这个理论,我被要求创建一个STA组件,其中一个方法接受一个整数并返回整数乘以2。该组件将托管在服务中,并将运行测试。
可以在C#中创建这样的东西,还是有必要用C ++创建它?
如果可能的话,你能包括一些代码吗?
编辑:(根据韩的建议编码)
using System.Runtime.InteropServices;
namespace STADemo
{
[ComVisible(true)]
public class STAClass
{
public int Calculate(int value)
{
return 2*value;
}
}
}
答案 0 :(得分:3)
这是COM coclass的属性。您可以使用[ComVisible]属性创建一个。您使用Regasm.exe注册它,它将写入ThreadingModel注册表项。它设置为“两个”。你必须把它改成“公寓”。
这不是一个非常理智的方式,你只会证明你已经知道的东西:从一个线程到另一个线程的调用比直接调用慢得多。只需使用调试器即可。启用非托管调试并密切关注Debug + Windows + Threads窗口。如果您在单步执行构造函数调用时看到另一个弹出窗口,那么您将发出COM正在创建辅助线程的信号,以便为COM组件提供安全的回家。很可能在服务中,默认情况下它没有STA线程,除非你自己创建一个。 Thread.SetApartmentState()调用。
答案 1 :(得分:1)
Windows服务使用MTA线程模型。您尚未指定可疑导致速度减慢的COM组件的确切模型。如果在'Apartment'
注册表项中将它们标记为''
或ThreadingModel
(空白),则可能确实会损害性能,因为所有调用都将从Windows服务的当前线程封送到COM创建的专用线程来托管组件。
如果您确实需要证明这一点,可以通过提供[ComRegisterFunction]
的自定义注册方法,在C#中创建单线程或单元线程组件。以下an example使用ComRegisterFunction
将组件标记为Apartment
。
请注意,如this article中所述,类工厂对象如何处理线程的单线程和单元线程组件之间仍然存在细微差别。单线程组件非常少见,您的组件很可能是单元线程的,但请务必检查其注册表项。