C# 线程公寓状态
全部,C# 线程公寓状态,c#,multithreading,C#,Multithreading,全部, 我在C#中使用线程已经有一段时间了,但对于线程的单元状态到底意味着什么,我仍然有点困惑。我知道WinForms必须始终使用STA公寓状态(与MTA相反),但我仍然不清楚公寓状态的含义 这篇由Raymond Chen撰写的关于新旧事物的博文介绍了STA和MTA线程模型背后的一些历史: […]COM培养了两种性格,一种是 专注于GUI客户和 另一个关注点是非GUI 客户。对于非GUI客户, 其他功能,如 增加了多线程公寓, 因为客户没有做GUI 多线程公寓 没有GUI规则的负担。 他们没有给
我在C#中使用线程已经有一段时间了,但对于线程的单元状态到底意味着什么,我仍然有点困惑。我知道WinForms必须始终使用STA公寓状态(与MTA相反),但我仍然不清楚公寓状态的含义 这篇由Raymond Chen撰写的关于新旧事物的博文介绍了STA和MTA线程模型背后的一些历史: […]COM培养了两种性格,一种是 专注于GUI客户和 另一个关注点是非GUI 客户。对于非GUI客户, 其他功能,如 增加了多线程公寓, 因为客户没有做GUI 多线程公寓 没有GUI规则的负担。 他们没有给我发信息 相互沟通;他们用 内核对象和 WaitForSingleObject。人人都赢, 对吧? 是的,每个人都赢了,但是你 你必须知道你的面包是哪一面 奉承。如果初始化GUI 线程作为多线程单元, 你违反了假设 多线程公寓在哪 我们是被发明的![……]
COM有着非常崇高的目标。其中之一是线程是一个编程细节,很难正确处理,应该由支持库管理。与.NET非常不同,在.NET中,完全由您以线程安全的方式使用非线程安全的类 这是通过注册表实现的,COM类发布ThreadingModel注册表项,该注册表项说明它支持哪种线程。到目前为止,它们中的大多数使用“单元”,这是一种有点不清楚的表示“我不支持多线程”的方式。这是COM确保以线程安全的方式调用所有方法的信号。如果您的程序从工作线程调用一个方法,那么COM负责将工作线程的调用封送到创建实例的线程。从而自动确保以线程安全的方式使用服务器。与Control.Invoke和Dispatcher.Invoke的工作方式不同,但完全是自动的 这当然是一个奇妙的魔法,但是你的程序确实需要一些合作。如果没有您的帮助,COM无法封送这样的调用。当您的程序创建线程时,它必须调用CoInitialize()来告诉COM基础结构您希望参与COM调用。那时,你必须告诉它你创建了什么样的线程。有两种,以“公寓”类型区分。有STA(单线程单元)和MTA(多线程单元)。STA线程是一个友好的COM组件,不支持线程。MTA线程不可用 不过,这种公寓有一个价格标签。创建STA时,必须遵循STA规则。这有点苛刻:
- 您必须启动Windows消息循环
- 你永远不能阻止线程
虽然COM可能看起来已经死了,但公寓在Windows编程中仍然是一件大事。NET框架对它们有明确的支持。在STA线程上调用Thread.Join()或Monitor.Enter(),例如,通过COM显式地verboten,使CLR泵成为一个消息循环。其他工件是您在GUI应用程序的Main()方法上看到的[STAThread]属性和Thread.SetApartmentState(),这是以正确方式获取CLR调用CoInitialize()的方法。剪贴板、拖放和shell对话框(如OpenFileDialog)等GUI功能明确要求STA工作。创建任何窗口的线程都应该始终是STA线程。不过……这两种模型之间有什么区别?也许举个例子?@koumides-除了更改入口点上的属性(
[STAThread]
vs[MTAThread]
)外,C代码没有太大区别。UI线程必须是STA。如果你弄错了,你可能会观察到车辆行为、碰撞、死锁等。我真的不知道你在寻找什么样的例子。如果你直接使用WinF32编码(不使用WinFrm(使用C、C++或C p/pUnk调用),那么,是的,将会有不同。@ KouMIDES——总之,C语言中的开发,我不太了解细节,也不需要知道。有关您的问题的可能更好的答案,请参阅。可能的副本包括: