STAThread 和多线程

发布于 2024-07-06 18:59:40 字数 441 浏览 10 评论 0原文

来自 MSDN 关于 STAThread 的文章:

表示应用程序的 COM 线程模型是单线程单元 (STA)。

,这是整篇文章。)

(作为参考 公寓……好吧,这超出了我的想象。 另外,我在某处读到,除非您的应用程序使用 COM 互操作,否则该属性实际上根本不执行任何操作。 那么它到底有什么作用,以及它如何影响多线程应用程序? 多线程应用程序(包括使用 Timer 到异步方法调用的任何人,而不仅仅是线程池等)是否应该使用 MTAThread,即使它“只是为了安全”? STAThread 和 MTAThread 实际上是做什么的?

From the MSDN article on STAThread:

Indicates that the COM threading model for an application is single-threaded apartment (STA).

(For reference, that's the entire article.)

Single-threaded apartment... OK, that went over my head. Also, I read somewhere that unless your application uses COM interop, this attribute actually does nothing at all. So what exactly does it do, and how does it affect multithreaded applications? Should multithreaded applications (which includes anything from anyone using Timers to asynchronous method calls, not just threadpools and the like) use MTAThread, even if it's 'just to be safe'? What does STAThread and MTAThread actually do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如痴如狂 2024-07-13 18:59:41

单元线程是一个 COM 概念; 如果您不使用 COM,并且您调用的 API 都没有“在幕后”使用 COM,那么您无需担心公寓。

如果您确实需要了解公寓,那么详细信息可以获取 有点复杂; 一个可能过于简化的版本是,标记为 STA 的 COM 对象必须在 STAThread 上运行,而标记为 MTA 的 COM 对象必须在 MTA 线程上运行。 使用这些规则,COM 可以优化这些不同对象之间的调用,避免在不必要的地方进行封送。

Apartment threading is a COM concept; if you're not using COM, and none of the APIs you call use COM "under the covers", then you don't need to worry about apartments.

If you do need to be aware of apartments, then the details can get a little complicated; a probably-oversimplified version is that COM objects tagged as STA must be run on an STAThread, and COM objects marked MTA must be run on an MTA thread. Using these rules, COM can optimize calls between these different objects, avoiding marshaling where it isn't necessary.

追风人 2024-07-13 18:59:41

它的作用是确保调用 CoInitialize 并将 COINIT_APARTMENTTHREADED 指定为参数。 如果您不使用任何 COM 组件或 ActiveX 控件,它对您完全没有影响。 如果你这样做了,那就很关键了。

单元线程的控件实际上是单线程的,对它们的调用只能在创建它们的单元中处理。

来自 MSDN 的更多详细信息:

在单线程中创建的对象
公寓(STA)接收方法调用
仅来自他们公寓的线程,所以
调用被序列化并且仅到达
在消息队列边界(当
Win32 函数 PeekMessage 或
SendMessage 被调用)。

在 COM 线程上创建的对象
多线程单元 (MTA) 必须
能够接收来自的方法调用
随时其他线程。 你会
通常实施某种形式的
多线程中的并发控制
使用 Win32 的对象代码
同步原语,例如
关键部分、信号量或
互斥体有助于保护对象的
数据。

当一个对象被配置为
在中性线程单元中运行
(NTA) 由位于的线程调用
STA 或 MTA,该线程
转移至 NTA。 如果这个线程
随后调用CoInitializeEx,
调用失败并返回
RPC_E_CHANGED_MODE。

What that does it it ensures that CoInitialize is called specifying COINIT_APARTMENTTHREADED as the parameter. If you do not use any COM components or ActiveX controls it will have no effect on you at all. If you do then it's kind of crucial.

Controls that are apartment threaded are effectively single threaded, calls made to them can only be processed in the apartment that they were created in.

Some more detail from MSDN:

Objects created in a single-threaded
apartment (STA) receive method calls
only from their apartment's thread, so
calls are serialized and arrive only
at message-queue boundaries (when the
Win32 function PeekMessage or
SendMessage is called).

Objects created on a COM thread in a
multithread apartment (MTA) must be
able to receive method calls from
other threads at any time. You would
typically implement some form of
concurrency control in a multithreaded
object's code using Win32
synchronization primitives such as
critical sections, semaphores, or
mutexes to help protect the object's
data.

When an object that is configured to
run in the neutral threaded apartment
(NTA) is called by a thread that is in
either an STA or the MTA, that thread
transfers to the NTA. If this thread
subsequently calls CoInitializeEx, the
call fails and returns
RPC_E_CHANGED_MODE.

牵你的手,一向走下去 2024-07-13 18:59:41

STAThread 写在 C# GUI 项目的 Main 函数之前。 它什么也不做,只是允许程序创建单个线程。

STAThread is written before the Main function of a C# GUI Project. It does nothing but allows the program to create a single thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文