【问题标题】:Winforms: One COM object needs an STAThread, the other needs an MTAThread. How can I use them?Winforms:一个 COM 对象需要一个 STAThread,另一个需要一个 MTAThread。我该如何使用它们?
【发布时间】:2010-12-04 01:21:09
【问题描述】:

我正在尝试使用两个 COM 组件构建一个 Winforms 应用程序。但是,其中一个组件仅在使用 [MTAThread] 时有效,而另一个仅在 [STAThread] 时有效。

推荐的解决方案是什么?

【问题讨论】:

    标签: c# winforms com mta apartment-state


    【解决方案1】:

    Windows 表单要求 [STAThread] 出现在其主入口点上。它只能在单线程单元状态下工作。您可以在 Windows 窗体的 UI 线程上使用您的 STA COM 对象,没有任何问题。

    对此的典型方法是创建您自己的线程,并将Thread.ApartmentState 设置为单独线程的 MTA(尽管这是默认设置)。在该线程中初始化和使用您的 MTA 线程 COM 组件。

    ThreadStart threadEntryPoint = ...;
    
    var thread = new Thread(threadEntryPoint);
    thread.ApartmentState = ApartmentState.MTA;  // set this before you call Start()!
    thread.Start();
    

    【讨论】:

    • A la new Thread(() => { COMObject = new COMObject(); ...etc }).Start() ?
    • 是的。通常,我不会将 lambda 用于新线程,只是因为线程方法往往更长,但这会很好......新线程默认为 MTA,因此您可以为 MTA 线程执行此操作。它只是不能在 GUI 线程上,因为 Windows 窗体需要 STA。
    • 我一直在尝试使用线程,但它仍然无法正常工作。不过,我的 winform 似乎与 [MTAThread] 一起工作正常。还有什么想法吗?
    • @hb:里德不是在开玩笑。不要将主 gui 线程放入 MTA。生命会爆炸。
    • @Reed:我希望您不介意我在您的答案中添加了一个简短的代码示例。 ApartmentThread 应该在线程启动之前设置。我想我会将这一点添加到您的答案中。
    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2019-10-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 2022-01-05
    相关资源
    最近更新 更多