当您使用 Visual Studio 创建一个空的WinForms应用程序时,该模板具有STAThread
主应用程序类中的属性。
我一直在阅读一些关于它的文档,但我不确定我是否完全理解它。
真的,我对此有一些疑问:
- 为什么要添加这个属性?
- 这是什么意思?
- 如果删除此属性会发生什么?
引用MSDN 博客,
当应用 STAThreadAttribute 时,它将当前线程的单元状态更改为单线程。无需对 COM 和线程进行大量讨论,此属性可确保当前线程与可能希望通过 COM 与其通信的其他线程之间的通信机制。当您使用 Windows 窗体时,根据您使用的功能,它可能使用 COM 互操作来与操作系统组件进行通信。剪贴板和文件对话框就是很好的例子。
1、为什么要添加这个属性?
因为它是 ActiveX 对象模型所要求的。您可以将 ActiveX 控件放在 WinForm 上(因此它是为了兼容性)或者某些 .NET 类使用需要该属性的本机控件。
2. 什么意思?
这意味着线程在单线程单元模型中运行。
3. 如果你删除这个属性会发生什么?
如果删除该属性,则行为未定义。该程序可能会随机失败,有时会出现合理的错误消息。例如,事情可能现在可以工作,然后与服务包中断。
3.如果你删除这个属性会发生什么?
我只是添加一个简单的例子来演示这个问题。
我用一个按钮和一个 OpenFileDialog 创建了简单的 WinForms 应用程序。单击按钮时,我运行一个显示 openFileDialog 的线程。我在使用和不使用 STAThread 的情况下启动应用程序,单击按钮的结果是相同的 - 它引发异常“跨线程操作无效:从创建它的线程以外的线程访问的控制 'Form1'”。看起来好像没有什么区别。但不是。
然后我通过调用以下方法更改了显示 openFileDialog:
private void ShowOFD()
{
if (InvokeRequired)
{
BeginInvoke(new Action(ShowOFD));
return;
}
openFileDialog1.ShowDialog(this);
}
使用 STAThread,它可以正常工作。如果没有 STAThread,它会引发异常:“在进行 OLE 调用之前,必须将当前线程设置为单线程单元 (STA) 模式。确保您的 Main 函数上标记了 STAThreadAttribute。仅当调试器附加到时才会引发此异常过程”。
然后我在没有调试器的情况下多次启动该应用程序(与 Visual Studio 分离)。一次应用程序只是静默关闭,另一次应用程序关闭并显示“vshost 已停止工作”消息
这意味着 Windows 窗体程序使用单线程单元状态。不支持 MTA 和自由线程单元状态。