【问题标题】:How to create a STA (Single Threaded apartment) control in VS2010如何在VS2010中创建一个STA(单线程单元)控件
【发布时间】:2013-09-20 15:13:41
【问题描述】:

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

【问题讨论】:

    标签: c# c++ visual-studio-2010 singlethreadmodel


    【解决方案1】:

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

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

    【讨论】:

    • 嗨,汉斯,我在问题中添加了代码:这是您的建议吗?
    【解决方案2】:

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

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

    请注意,在类工厂对象如何处理线程方面,单线程组件和单元线程组件之间仍然存在细微差别,如this article 中所述。单线程组件非常少见,您的组件很可能是单元线程的,但请务必检查它们的注册表项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      相关资源
      最近更新 更多