gpt4 book ai didi

c# - 线程公寓状态

转载 作者:太空狗 更新时间:2023-10-30 00:16:50 25 4
gpt4 key购买 nike

全部,

我在 C# 中使用线程有一段时间了,但我仍然对线程的单元状态的真正含义感到有点困惑。我知道 WinForms 必须始终使用 STA 公寓状态(与 MTA 相对),但我仍然不清楚公寓状态是什么。

最佳答案

COM 有非常崇高的目标。其中之一是线程是一个很难正确处理的编程细节,应该由支持库来管理。与 .NET 非常不同,在 .NET 中,以线程安全的方式使用非线程安全的类完全取决于您。

这通过注册表工作,COM coclass 发布 ThreadingModel 注册表项,说明它支持哪种线程。到目前为止,他们中的大多数人都使用“公寓”,这是一种不太明确的方式来表达“我不支持多线程”。这是 COM 确保以线程安全方式调用所有方法的信号。如果您的程序从工作线程调用方法,则 COM 负责将调用从工作线程编码到创建实例的线程。从而自动确保服务器以线程安全的方式使用。与 Control.Invoke 和 Dispatcher.Invoke 的工作方式不同,但完全是自动的。

这当然是美妙的魔法,但您的程序确实需要进行一些合作。没有您的帮助,COM 无法像那样编码调用。当您的程序创建线程时,它必须调用 CoInitialize() 来告诉 COM 基础结构您要参与 COM 调用。那时,您必须告诉它您创建的线程是什么种类。有两个,以“公寓”类型区分。有STA(单线程单元)和MTA(多线程)。 STA 线程是不支持线程的 COM 组件的好客之家。 MTA 线程不是。

不过,这种公寓是有价格标签的。创建 STA 时,您必须遵守 STA 规则。有点龙:

  • 必须使用 Windows 消息循环
  • 永远不能阻塞线程

消息循环是 COM 将调用从一个线程编码到另一个线程的机制。需要永不阻塞规则来防止死锁。虽然是龙语,但它是程序的 UI 线程的工作方式。这不是巧合。

在 MTA 线程上创建单元线程 COM 对象也是有代价的。这样的线程不是一个好归宿,它不遵循 STA 规则。 COM 无济于事,无法对方法调用进行编码。 COM 介入并实际创建它自己的 STA 线程,为对象提供一个好客的家。很好,但并不便宜,因为这会消耗一个线程并且每个方法调用都被编码,这会为每个调用增加很多开销。

COM 线程支持非常好,它可以处理 98% 的时间,而无需执行任何特殊操作。然而,正是这 2% 会导致严重的偏头痛,您几乎无能为力。它的扩展性也很差,这可能是 .NET 没有类似功能的最大原因。

虽然 COM 可能看起来已经死了,但单元在 Windows 编程中仍然是一个非常重要的问题。 .NET 框架对它们有明确的支持。例如,在 STA 线程上调用 Thread.Join() 或 Monitor.Enter(),COM 明确禁止,使 CLR 泵成为消息循环。其他工件是您在 GUI 应用程序的 Main() 方法和 Thread.SetApartmentState() 上看到的 [STAThread] 属性,这是让 CLR 调用 CoInitialize() 的正确方法。剪贴板、拖放和外壳对话框(如 OpenFileDialog)等 GUI 功能明确要求 STA 才能工作。创建任何窗口的线程应始终是 STA 线程。

关于c# - 线程公寓状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5168815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com