1

我有一个托管组件的 .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;
        }
    }
}
4

2 回答 2

3

这是 COM coclass 的属性。您可以使用 [ComVisible] 属性创建一个。您使用 Regasm.exe 注册它,它将写入 ThreadingModel 注册表项。它设置为“两者”。您必须将其更改为“公寓”。

这不是一种非常理智的方法,您只会证明您已经知道的:将调用从一个线程编组到另一个线程比直接调用要慢得多。只需使用调试器即可。启用非托管调试并密切关注 Debug + Windows + Threads 窗口。如果您在单步执行构造函数调用时看到另一个弹出窗口,那么您将收到一个信号,表明 COM 正在创建一个帮助线程,以便为 COM 组件提供一个安全的家。很可能在服务中,默认情况下它没有 STA 线程,除非您自己创建一个。Thread.SetApartmentState() 调用。

于 2013-09-20T15:48:38.873 回答
1

Windows 服务使用 MTA 线程模型。您尚未指定可能导致减速的 COM 组件的确切型号。如果它们在其注册表项中被标记为'Apartment'''(空白)ThreadingModel,那可能确实会损害性能,因为所有调用都将从 Windows 服务的当前线程编组到由 COM 创建的专用线程来托管组件。

如果您确实需要证明这一点,您可以在 C# 中通过提供自定义注册方法来创建单线程或单元线程组件[ComRegisterFunction]。这是一个使用将组件标记为的示例ComRegisterFunctionApartment

请注意,在类工厂对象如何处理线程方面,单线程组件和单元线程组件之间仍然存在细微差别,如本文所述。单线程组件确实很少见,您的组件很可能是单元线程的,但无论如何都要确保检查它们的注册表项。

于 2013-09-20T23:35:39.073 回答