为什么 WinForms 应用程序默认是 STAThread?
当您使用 Visual Studio 创建空的 WinForms 应用程序时,模板在主应用程序类中具有 STAThread
属性。
我一直在阅读一些有关它的文档,但我不确定我是否完全理解它。
我确实有一些疑问:
- 为什么要添加这个属性?
- 这是什么意思?
- 如果删除这个属性会发生什么?
When you create an empty WinForms application with Visual Studio, the template has the STAThread
attribute in the main application class.
I have been reading some docs about it, but I'm not sure if I understood it at all.
Really I have some questions about it:
- Why is this attribute added?
- What does it mean?
- What happens if you remove this attribute?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
引用MSDN 博客,
To quote from an MSDN blog,
因为它是 ActiveX 对象模型所需要的。您可以将 ActiveX 控件放在 WinForm 上(因此它是为了兼容性)或某些 .NET 类使用需要该属性的本机控件。
这意味着线程在单线程单元模型中运行。
如果删除该属性,则行为未定义。该程序可能会随机失败,有时会出现明显的错误消息。例如,现在可能一切正常,然后由于服务包而中断。
Because it is required by the ActiveX object model. And you can drop ActiveX controls on a WinForm (so it is there for compatibility) OR some .NET classes use native controls which require that attribute.
It means the thread runs in the single-threaded apartment model.
If the attribute is removed, the behavior is undefined. The program may fail at random, with sometimes sensible error messages. For example, things may work now, then break with a service pack.
我只是添加一个简单的例子来说明问题。
我创建了带有按钮和 OpenFileDialog 的简单 WinForms 应用程序。单击按钮时,我运行一个显示 openFileDialog 的线程。我在使用和不使用 STAThread 的情况下启动应用程序,单击按钮的结果是相同的 - 它会抛出异常“跨线程操作无效:从创建它的线程以外的线程访问控制‘Form1’”。
看起来好像没有什么区别。但没有。
然后我通过调用以下方法更改了 openFileDialog 的显示:
使用 STAThread,它按预期工作正常。如果没有 STAThread,它会抛出异常:
“在进行 OLE 调用之前,当前线程必须设置为单线程单元 (STA) 模式。确保您的 Main 函数上标记有 STAThreadAttribute。仅当调试器附加到进程时才会引发此异常”。
然后我在没有调试器的情况下多次启动该应用程序(与 Visual Studio 分离)。一次应用程序只是默默关闭,另一次应用程序关闭并显示消息“vshost 已停止工作”
I just add a simple example which demonstrates the problem.
I created simple WinForms app with a button and an OpenFileDialog. On button click I run a thread which shows the openFileDialog. I launch the app with and without STAThread and results of clicking the button are the same - it throws the exception "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on".
It looks as if there is no difference. But no.
Then I changed showing the openFileDialog by calling the method below:
With STAThread it works fine as expected. Without STAThread it throws the exception:
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process".
Then I launch the app several times without debugger (detached from visual studio). One time the app just silently closed, another time the app closed with the message "vshost has stopped working"
这意味着 Windows 窗体程序使用单线程单元状态。不支持 MTA 和自由线程单元状态。
It means that Windows Forms programs use a single-threaded apartment state. MTA and free threaded apartment states are not supported.