为什么WPF需要将STAThread属性应用于Main方法?

15

我刚接触WPF,在每个教程中都看到[System.STAThread] 属性被应用于Main方法,或让读者这样做。

这个属性是否真的“必需的”?如果是,为什么呢?

2个回答

34

这与WPF不太相关,更多是Windows的要求,源于.NET之前的Windows表单和控件的原始设计。

STAThread是"Single-Threaded Apartments"的缩写,指的是当前(主)线程使用的线程模型。线程模型决定了其他.NET和COM应用程序将如何与您的应用程序(和其线程)通信。单线程应用程序模型要求单个对象在同一时间内只能“存在于”一个STA线程中,而不是MTA线程模型;并且只允许通过对象序列化进行跨线程间传递指向数据的指针。

基本上,[STAThread]声明可以让其他应用程序知道你的线程策略在接收数据时的要求。STA模型是Windows线程/应用程序最常见的线程模型;但你有时会遇到某些代码,如果从STA模型的线程中调用该代码,则无法运行,因为它被设计为以不符合STA限制的方式在线程边界上发送/接收数据。事先知道给定线程的公寓模型可以使IDE在编译时捕获这些异常,而不是在运行时尝试在线程边界上使用对象时出现令人讨厌的访问冲突错误。

您可以从MSDN文章http://msdn.microsoft.com/en-us/library/ms680112(VS.85).aspx中了解STA和MTA线程。

请注意,即使是WPF之前的普通.NET应用程序也需要在main()上方加上[STAThread]声明。


6

这篇博客文章中有一个很好的答案。

引用博客中的内容:

当应用STAThreadAttribute时,它会将当前线程的单元状态更改为单线程。不涉及COM和线程讨论,此属性确保了当前线程与可能通过COM想要与其通信的其他线程之间的通信机制。当您使用Windows Forms时,根据您使用的功能,它可能正在使用COM互操作来与操作系统组件通信。这些的好例子是剪贴板和文件对话框。

Windows Forms不支持在MTA或自由线程公寓中。使用Windows Forms的应用程序应始终声明它们正在使用的公寓样式,因为某些其他组件可能会错误地初始化线程的公寓状态。


如果对于初学者来说不是“过于复杂”的话,那就不需要简化了。我喜欢阅读 :) - Madi D.
2
仍然在SO上有一个摘要以供参考是很好的,如果该博客离线、帖子被删除、Microsoft陷入地狱火球等情况发生也能用得上。 - Matthew Scharley

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