[STAThread]是什么作用?

358

我正在学习C# 3.5,想知道我们程序中的[STAThread]是什么作用?

3个回答

307

STAThreadAttribute本质上是与Windows消息泵通信的COM组件的要求。虽然核心的Windows Forms不使用COM,但许多操作系统的组件,如系统对话框,确实使用了这项技术。

MSDN稍微详细地解释了原因:

STAThreadAttribute表示应用程序的COM线程模型是单线程公寓。该属性必须存在于使用Windows Forms的任何应用程序的入口点上;如果省略了该属性,则Windows组件可能无法正常工作。如果该属性不存在,则应用程序使用不支持Windows Forms的多线程公寓模型。

这篇博客文章 (为什么需要STAThread?)也很好地解释了这个要求。如果您想更深入地了解CLR级别的线程模型如何工作,请参阅2004年6月的这篇MSDN Magazine文章 (已存档,2009年4月)。


1
你知道为什么CompactFramework不支持[STAThread]吗? - bvdb
5
这个回答对于像我这样的凡人来说相当易懂。仅供参考。该问题涉及到多线程编程中的ApartmentState(公寓状态)概念,其中包括两种类型:STA(单线程公寓)和MTA(多线程公寓)。STA主要用于单线程应用程序,而MTA则适用于多线程应用程序。 - Barış Akkurt

61

它告诉编译器你正在使用单线程公寓模型。这是COM的一个棘手问题,通常用于Windows Forms(GUI),因为COM组件拖放(感谢@AnthonyWJones)使用Win32进行绘制实现为STA。如果您从多个线程使用STA模型的某些东西,则会出现损坏的对象。

这就是为什么您必须从另一个线程调用Gui(如果您已经编写了任何表格代码)的原因。

基本上不要担心它,只需接受Windows GUI线程必须标记为STA,否则会发生奇怪的事情。


6
STAThread与访问GUI时需要调用主线程无关。这仅仅是由于Windows消息泵的性质导致的,在多线程应用程序中通常无法避免。 - Noldorin
4
实际上,它只涉及处理COM组件,比如操作系统对话框和第三方组件。 - Noldorin
4
Win32没有线程单元的概念,这个概念是由COM引入的。COM将原本完全与线程无关的系统(Windows消息泵)“重新分配任务”,作为在COM线程单元中同步/序列化代码执行的一种方法。 - AnthonyWJones
2
请接受Windows GUI线程必须标记为STA,否则会发生奇怪的事情。:))) - Nipuna
1
@Noldorin “调用主线程的要求” - 严格来说这并不是一个要求。跨线程异常在调试器之外不会发生。参考:https://dev59.com/wW865IYBdhLWcg3wIa7M。但并不是说你不应该解决这个问题! - Shiv
显示剩余2条评论

35

STAThreadAttribute标记一个线程,以使用单线程COM公寓(如果需要COM)。默认情况下,.NET根本不会初始化COM。只有在需要COM时,例如创建COM对象或COM控件或需要拖放时,才会初始化COM。当发生这种情况时,.NET调用底层的CoInitializeEx函数,该函数接受一个标志,指示是否将线程加入多线程或单线程公寓。

阅读更多信息此处(存档,2009年6月)

为什么需要STAThread?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接